如何使用PHP批量插入数千个WooCommerce产品?

时间:2017-10-23 作者:jestrange

我有大约5000个Excel格式的产品要通过HTML-PHP上传到Woocommerce db,我如何通过API/Direct db或两者以最佳方式实现这一点?

Clarification: 我不想使用内置的,我需要它作为PHP代码,以便在导入时添加自定义功能(就像我需要在自定义表上记录新的/更新的/导入的产品)。

2 个回复
SO网友:janh

是什么阻止你使用officially documented way to import products from csv? 如果您运行的是旧版本,则an extension 这也是同样的道理。

SO网友:HU ist Sebastian

虽然可以将数据直接插入到数据库中,但这需要大量的工作,而且数据集结构中的插入/更改错误会使导入完全无用,API将是插入产品的更好、更安全的方法。

然而,5000个产品太多了,使用一个函数将它们全部插入可以轻松超过PHP执行时间限制。因此,如果您使用“手动”导入器(例如,单击按钮并运行导入),最好的操作方式是创建一个分两步工作的管理屏幕。

步骤1:导入CSV并读取数据集。将数据集保存到临时数据库表或管理屏幕上的表中。

步骤2:编写一个Ajax函数,通过API在管理屏幕上导入1个产品。在返回的数据中包括有关成功(或未成功)导入哪个产品的信息。

步骤3:为每个函数编写一个jQuery,每次只向Ajax导入函数发送一个产品。您可以使用jQuery计时插件来确保通过ajax每x毫秒发送一个产品。单击即可启动该功能。现在你只要等到所有的产品都进口了。如果你加入一个进度条,你会得到一个很好的视觉反馈,有多少产品已经进口。

下面粘贴的代码只是关于如何实现这一点的一般想法。请注意,实际处理数据的部分并不在其中,因为我a)不知道CSV文件是如何构建的,b)我懒得查看woocommerce api的具体工作方式。

<?php
add_action(\'admin_menu\', \'add_menu_page_for_big_import\');

function add_menu_page_for_big_import() {
    add_menu_page(\'Import all the products\', \'Imports\', \'manage_options\', \'product-imports\', \'all_the_products_import_output\',\'dashicons-welcome-add-page\' ,22);
}

function all_the_products_import_output(){
    wp_enqueue_media();
    wp_enqueue_script(\'jquery\');
    wp_enqueue_script(\'media-upload\');
    wp_enqueue_script(\'jquery-timing\',\'http://creativecouple.github.io/jquery-timing/jquery-timing.min.js\',array(\'jquery\'));
    wp_enqueue_script(\'jquery-ui-progressbar\');
    wp_enqueue_style(\'jquery-ui-smoothness-style\',\'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/smoothness/jquery-ui.min.css\');
    ?>
    <div class="wrap">
    <?php 
     if(isset($_POST[\'filename\'])) {
    //do whatever you need to do with the csv. Import it, put it in an array
    ?>
    <table class="imports">
        <?php
        $import_counter = 0;
        foreach($product_array as $product){
            $import_counter++;
            ?>
            <tr data-prodnumber="<?php echo $product[\'product_number\']; ?>">
                <?php
                foreach($product as $key => $productfield){
                    ?>
                    <td class="<?php echo $key; ?>"><?php echo $productfield; ?></td>
                    <?php
                }
                ?>
            </tr>
            <?php
        }
        ?>
    </table>
    <span class="importpreview"><?php echo $import_counter; ?> Products for import.</span>
    <p>Click the button to start the import. Don\'t close the window until import is finished.</p>
    <div id="progressbar"></div>
    <p>
        <a class="button goimport" href="#" id="import_start">Start import</a>  
    </p>
    <span class="resultlabel">Result: </span><br />
    <span class="result" data-errors="0" data-imported="0">
        Products imported: <span class="updated">0</span><br />
        Errors: <span class="error">0</span>
    </span><br />
    <script>
        var progressbar;
        var aktval = 0;
        jQuery(document).ready(function($){
            progressbar = $(\'#progressbar\').progressbar({
                max: <?php echo $import_counter; ?>
            });
        });
    </script>
    <?php
     } else {
    ?>
    <h2>Import Products</h2>
<form name="import_form" method="post" action="<?php echo str_replace( \'%7E\', \'~\', $_SERVER[\'REQUEST_URI\']); ?>">
    <label for="filename">CSV-File</label>
    <input id="upload_txt" type="text" name="filename" value="" />
    <input id="upload_button" type="button" value="upload csv file" />
    <input type="submit" value="next step" />
</form>
<?php } ?>
<script>
        jQuery(document).ready(function($) {
            $(\'.goimport\').click(function(event){
                event.preventDefault();
                var mycounter = 0;
                $(\'table.importdata tr\').each($).wait(500,function(){
                    //by using the wait command (supplied by the jquery timing plugin), we ensure that not all the
                    //products are sent at once, but only every .5 seconds
                    mycounter++;
                    postdata = new Object();
                    postdata[\'action\'] = \'import_all_the_products_action\';
                    //put into the postdata all the data from the table you need like this:
                    postdata[\'keyname\'] = $(this).find(\'td.keyname\').html();
                        $.post(ajaxurl, postdata, function(response){
                            if(response.message == \'SUCCESS\'){
                                $(\'span.result\').data(\'imported\',parseInt($(\'span.result\').data(\'imported\'))+1);
                                $(\'span.result .updated\').html(parseInt($(\'span.result .updated\').html())+1);
                            }else if(response.message == \'ERROR\'){
                                $(\'span.result\').data(\'errors\',parseInt($(\'span.result\').data(\'errors\'))+1);
                                $(\'span.result .error\').html(parseInt($(\'span.result .error\').html())+1);
                            }
                            aktval++;
                            progressbar.progressbar( "value", aktval );
                        },"json");
                    }
                });
            });
            var _custom_media = true,
            _orig_send_attachment = wp.media.editor.send.attachment;
            $(\'#upload_button\').click(function(e) {
                var send_attachment_bkp = wp.media.editor.send.attachment;
                var button = $(this);
                _custom_media = true;
                wp.media.editor.send.attachment = function(props, attachment){
                    if ( _custom_media ) {
                        $("#upload_txt").val(attachment.url);
                    } else {
                        return _orig_send_attachment.apply( this, [props, attachment] );
                    };
                }
                wp.media.editor.open(button);
                return false;
            });
        });
    </script>
</div>
<?php 
}

add_action( \'wp_ajax_import_all_the_products_action\', \'import_products_ajax_action\' );

function import_products_ajax_action() {
    //get all the data you need from the $_POST Variable like this.
    $keyname = $_POST[\'keyname\'];
    //do whatever you need to do with the product data. Import by api, or whatever.
    //put $success to true to give the info back to the admin screen
    //in $data, you can give back additional data
    if($success){
        echo json_encode(array(\'message\' => \'SUCCESS\',\'data\' => $data));
        die();
    } else {
        echo json_encode(array(\'message\' => \'ERROR\',\'data\' => $data));
        die();
    }
}

结束

相关推荐

Virtual Pages plugins

我很难让插件正常工作Virtual Pages (WordPress插件可简化虚拟页面的创建)我确实进行了编辑,根据查询创建了一个循环。add_action( \'gm_virtual_pages\', function( $controller ) { /* Creating virtuals pages for companies */ $args = array( \'post_type\' => array(\'companies\',), \'post_status\'