Поддержка Проблемы и решения Создать каталог — register_post_type() или метаданные

  • Доброго дня
    Прошу Вашей помощи в области понимания структуры хранения данных при создании каталога продукции. Суть такова: необходимо реализовать каталог продукции, в котором содержится информация о товарах со всеми продавцами и поставщиками данных товаров, т.е. результирующая таблица товаров, которая должна выводиться пользователю после выбора им всех параметров фильтрации товаров, имеющихся в БД, такова:
    Наименование_товара Производитель Поставщик Данные_поставщика/производителя Цена.
    Для реализации я создаю свой тип записи при помощи register_post_type(), создаю свои таксономии для классификации товаров при помощи register_taxonomy(), но не пойму как хранить в структуре БД сущность самого товара и связанного с ним поставщика и производителя. Т.е. если товар — это мой тип записи, то производитель и поставщик это должны быть произвольные поля в таблице wp_postmeta, или же для производителя/поставщика нужно создавать ещё один тип записи? но тогда как их связать между собой тип записи товар и поставщик/производитель?
    Т.е. к примеру, имеется кирпич и его могут продавать/производить условно 10 разных компаний по разным ценам, тогда соответственно в таблице wp_posts будет 10 записей, связанных с произвольными полями в wp_postmeta (я склоняюсь к данному варианту) или в таблице wp_posts будет 10 записей товаров каким-то образом связанных с типом записи производитель/поставщик?
    Или имеет место какой-то третий вариант? (пытаюсь всё реализовать без плагинов и создания своих собственных таблиц)
    Извините, если написал замудрено, но пытался спросить максимально доступно. Буду благодарен за любую консультацию — не могу понять как верно хранить данные в данном случае. Помогите, пожалуйста

Просмотр 15 ответов — с 1 по 15 (всего 49)
  • Модератор Юрий

    (@yube)

    Если данных будет много и если предполагается фильтрация/сортировка по «вторичным признакам», то эффективнее использовать не post meta, а термы таксономий. Это обусловлено способом хранения данных в БД. То есть, товары — записи, производители и поставщики — таксономии. Атрибуты (адреса, телефоны и т.п.) производителей и поставщиков либо прямым текстом в term description, либо в term meta (на радость формалистам))). Цена — post_meta. Ну, я бы, наверно, делал так.

    @yube , спасибо огромное!) Получается один товар (т.е. одна запись из wp_posts) может быть связан с энным количеством записей из wp_terms (т.е. с продавцами). Но вопрос по поводу цены товара — цена товара устанавливается продавцом, а один товар могут продавать несколько продавцов и каждый продавец по своей цене, не пойму как в wp_postmeta задать несколько цен одному товару и привязать каждую цену к определенному продавцу?

    Модератор Юрий

    (@yube)

    как в wp_postmeta задать несколько цен одному товару

    Легко, но бесполезно.

    и привязать каждую цену к определенному продавцу?

    Никак. Мета привязывается только к ID записи.

    Придется делать разные товары. В этом нет ничего необычного, на том же Алиэкспресс можно найти в огромных количествах одну и ту же ерунду, выпускаемую одним и тем же производителем, но продаваемую разными продавцами по разным ценам, и это разные товары.

    В принципе для облечения жизни посетителей можно сделать еще одну таксономию, в которой терм будет, так сказать, обобщенным товаром, независимым от производителя и продавца («кирпич СЛД-150/25 ГОСТ379—95»), а к этому терму будут привязаны именно такие кирпичи от разных производителей и у разных продавцов.

    Понял, @yube , еще раз спасибо) буду в указанном Вами ключе продумывать структуру записей и таксономий. Можно ещё вопрос: теоретически я могу в wp_postmeta прописывать несколько цен товара, а идентифицировать каждую цену отдельного продавца по meta_key, где meta_key будет слагом соответствующей термы продавца? Ну и соответственно meta_value будет ценой данного продавца, по слагу в meta_key таким образом определю продавца, или такой подход в корне неправильный и цену по meta_key таким образом не удастся идентифицировать с продавцом?

    Модератор Юрий

    (@yube)

    по слагу в meta_key таким образом определю продавца

    Тоже вариант, но тут пахнет перебором: либо по всем продавцам проверять наличие мета-цены, либо каждый мета-ключ проверять, не является ли он продавцом. Впрочем, если продавцов мало и не предполагается активный рост их количества, вполне можно и перебором продавцов.

    @yube , можно ещё попросить Ваш совет по поводу таксономий — производители и поставщики. Выше Вы писали:

    Это обусловлено способом хранения данных в БД. То есть, товары — записи, производители и поставщики — таксономии.

    В моем случае у 80% товаров (всего в БД около 2500 товаров, их количество расти не будет) известны только поставщики, в остальных 20% случаях производитель одновременно является поставщиком (всего в справочнике около 1000 уникальных организаций). Подскажите, пожалуйста, лучше Производители и Поставщики оформлять как отдельные таксономии и ничего страшного что эти 20% организаций будут дублироваться в термах двух созданных таксономий, или же лучше делать одну таксономию «Организации» и далее определять по мета-полю каждой термы в wp_termmeta является организация поставщиком или производителем или и тем и тем одновременно ?

    Модератор Юрий

    (@yube)

    Я бы делал две таксономии. Хотя бы потому, что для получения списка всех производителей (или продавцов) не нужно делать никаких лишних телодвижений (я немного преувеличил, на самом деле немного нужно))). А Вы делайте так, как Вам удобней. Вам виднее, какие выборки понадобятся.

    p.s. Как показывает многолетний опыт, в процессе работы всегда оказывается нужно больше, чем планировалось изначально (Законы Мерфи неумолимы), поэтому лучше сразу в проект закладывать некоторую избыточность.

    • Ответ изменён 1 год, 8 месяцев назад пользователем Юрий. Причина: уточнил

    Понял, спасибо большое за совет. @yube , позвольте также спросить — есть ли какое-то ограничение по количеству на создание своих типов записей и таксономий к ним ? В моем случае, кроме Товаров, некоторым Организациям будут принадлежать также некоторые Вакансии и Услуги, которые они предлагают (ну и мало ли появится что-то еще))) т.к. товары, вакансии и услуги являются разными сущностями, я ведь могу для удобства выборок создать отдельными типами записей и Товары, и Вакансии, и Услуги и соответственно к каждому типу записи создать свои таксономии (где-то общие для всех, а где-то индивидуальные для каждого типа записи) ?

    Модератор Юрий

    (@yube)

    Смело создавайте типы и таксономии! Есть ограничения со стороны mysql по количеству записей в таблицах, так как суррогатный ключ не резиновый, а целочисленный. Но на практике 18 квинтилионов можно считать бесконечностью.

    @yube , еще раз спасибо. Создаю структуру будущего каталога и закралась мысль о будущем наполнении таблиц wp_posts, wp_postmeta, wp_term, wp_termmeta данными о товарах, организациях и т.п. Думаю не комильфо заполнять 2500 товаров и 1000 организаций ручками, если имеется готовый массив данных в Excel и его можно перевести в формат CSV. Вопрос в том, как реализовать данный алгоритм для WP. Ранее, когда я учился и писал сайты на php без CMS, я через форму брал файл, проверял его формат, и если все ОК — читал строки из файла при помощи fgetcsv() и полученный массив записывал в БД. Подскажите, пожалуйста, можно ли что-то подобное реализовать в админке WP ? — Т.е. добавить новую вкладку или нечто подобное (еще не приходилось добавлять какой-либо функционал в админку WP), а в ней создать форму c <input type='file' />, а далее обрабатывать файл при помощи все той же fgetcsv() и полученные данные записывать в БД при помощи wp_insert_post(), wp_insert_term(), update_post_meta(), update_term_meta(). Подскажите, пожалуйста, будет ли работать данный алгоритм в админке WP, и как в принципе, если можно, добавить данный функционал в админку ?
    Ниже, вряд ли конечно пригодится, но привожу фрагмент своего кода, которым я обрабатывал файлы CSV и записывал данные из них в БД:

    <?php
    if (isset($_POST['submit']) && $import=='bel') {
        if ($_FILES) {
            $name = $_FILES['filename']['name'];
            if ($_FILES['filename']['type']=='application/vnd.ms-excel') {
                move_uploaded_file($_FILES['filename']['tmp_name'], $name);
                echo "<h4 class='available'>FILE is LOADED: '$name'</h4>";
                $type='application/vnd.ms-excel';
            }
            else {
                    echo "<h4 class='taken'>FILE has not correct format or not exists</h4>"; exit();
                 }
        } else echo "<h4 class='taken'>Loading did NOT happen</h4>";
        if ((file_exists("$name")) && ($type)) {
                echo "<h4 class='available'>OK - FILE has correct format</h4>";
                $rowsCount = 100;
                $insertStmt = 'Insert into statistics_rb (parameter,parameter_unit,id_2010,id_2011,id_2012,id_2013,id_2014,id_2015,id_2016,id_2017,id_2018) values ';
                $row = 1;
                if (($handle = fopen("$name", "r")) !== FALSE) {
                    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
                        $num = count($data);
    					$row++;
                        if ($row > 2) {
    						$data_final = array_map('htmlentities', $data);
    						$rowsToInsert[] = '("' . implode('","', $data_final) . '")';
    						if ($rowsCount <= count($rowsToInsert)) {
    							$insertStmt_final = $insertStmt . implode(', ', $rowsToInsert);
    							$result=$conn->query($insertStmt_final);
    							$rowsToInsert = array();
    						}
                        }
                    }
                    if (!empty($rowsToInsert)) {
                        $insertStmt_final = $insertStmt . implode(', ', $rowsToInsert);
                        $result=$conn->query($insertStmt_final);
                        $rowsToInsert = array();
                    }
                    fclose($handle);    
                }
    	}
    }			

    @yube , я прошу прощения, описанный выше функционал импорта данных из файлов CSV в базу данных пытаюсь добавить при помощи функции add_menu_page() следующим образом:

    add_action( 'admin_menu', 'register_import_csv' );
    function register_import_csv(){
    add_menu_page( 'Импорт из CSV', 'Импорт из CSV', 'manage_options', 'import_csv/import_csv.php', '', 'dashicons-database-import', 81 );
    }

    Код страницы расположен в файле плагина import_csv.php . То что я прописал в файле отображается и без активации плагина.
    Подскажите, пожалуйста, сам плагин при этом получается не нужно активировать ?

    Модератор Юрий

    (@yube)

    То что я прописал в файле отображается и без активации плагина.

    Не может такого быть. Разве что скрипт подключен как часть другого плагина или темы. Или лежит не в plugins, а в mu-plugins

    Может я чего-то не понимаю… вот мой неактивированный плагин: http://prntscr.com/u6sopm, а вот форма, которую я прописал в файле плагина: http://prntscr.com/u6srg8

    @yube , я прошу прощения, Вы не подскажете, могу ли я меню, созданное в wp_nav_menu(), разместить в сайдбаре, в котором имеется один или несколько виджетов ? или отдельно создается меню и отдельно под ним виджеты в сайдбаре? не могу сообразить… (извиняюсь, если вопрос показался странным — на сайте без CMS данный блок с меню и записями оформлен цельным блоком и присутствует на всех страницах: http://prntscr.com/uasm0j. Как правильнее его реализовать в концепции WP ? )

    Модератор Юрий

    (@yube)

    меню, созданное в wp_nav_menu()

    wp_nav_menu() — функция вывода меню. Сами менюшки содаются в админке. Либо программно на лету, но это редкий случай высшего пилотажа 🙂

    разместить в сайдбаре

    Конечно. Среди штатных виджетов есть виджет «навигационное меню», в котором можно вывести любое из имеющихся (созданных) меню.

Просмотр 15 ответов — с 1 по 15 (всего 49)
  • Тема «Создать каталог — register_post_type() или метаданные» закрыта для новых ответов.