Ответы пользователя по тегу WordPress
  • Как удалить лишние атрибуты у изображений в Wordpress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Вот эту тучу data-атрибутов генерит не CMS, а какой-то из плагинов (или целый зоопарк плагинов), либо же в самой теме автор прописал это адище. Сам WordPress ничего такого не делает.

    <img class="alignnone size-medium wp-image-30" 
        src="https://wordpress.dev/wp-content/uploads/2017/08/test-300x196.jpg" 
        alt="Test" 
        width="300" 
        height="196" 
        srcset="https://wordpress.dev/wp-content/uploads/2017/08/test-300x196.jpg 300w, https://wordpress.dev/wp-content/uploads/2017/08/test.jpg 600w" 
        sizes="(max-width: 300px) 100vw, 300px">


    Это код, который выводится в стандартной теме Twenty Seventeen.
    Ответ написан
  • Как получить ссылку на определённую страницу?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    echo get_permalink( get_page_by_path( 'portfolio' ) );
    Ответ написан
    1 комментарий
  • Как вывести записи в category.php из acf?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    https://www.advancedcustomfields.com/resources/get...

    the_field( 'custom_title', 'options' );
    Ответ написан
    Комментировать
  • Wordpress: при отправки AJAX JSON экранируются кавычки?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Так $_POST и так будет содержать данные формы, зачем вы делаете JSON.stringify(obj) и конвертируете в строку? Именно эта строка потом и оборачивается в кавычки. И поскольку это строка, а не JSON прилетает на PHP, то и json_decode ее не может проглотить.

    Вот тут есть рабочий пример:
    https://www.sitepoint.com/jquery-php-ajax-json/
    Ответ написан
    2 комментария
  • Wordpress. Не работает кэширование. Что делать?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Еще один кэп тут. По коду вроде все норм, у меня вопрос - а в папке wp-content у вас есть drop-in object-cache.php, который является реализацией интерфейса кеша к вашему конкретному кеширующему бекенду (redis, memcache, memcached, APC и тд)?
    Ответ написан
    Комментировать
  • Как сделать поддомены копией основного сайта Wordpress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Попробуйте динамически устанавливать домен:

    https://codex.wordpress.org/Editing_wp-config.php#...
    https://codex.wordpress.org/Editing_wp-config.php#...

    Дополнительно обратите внимание на константы WP_CONTENT_URL, WP_PLUGIN_URL, COOKIE_DOMAIN и другие, содержащие URLы. Возможно, придется еще хукнуться в несколько фильтров (но не уверен - надо тестить).
    Ответ написан
    3 комментария
  • Как задать классы для ссылок при выводе произвольного меню через wp_nav_menu?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    +1 к ответу Александр, дополнительно лишь укажу, что как раз для случаев "вывести в удобной для себя верстке" существует Walker_Nav_Menu. Это на первый взгляд вам кажется, что достаточно получить массив пунктов (кстати, это можно сделать с помощью get_posts / WP_Query, если сильно надо) и сделать обычный foreach. На самом деле у меню есть такая штука как вложенность. Это дерево. А там где дерево - там рекурсия. И вместо того, чтобы писать какой-то свой рекурсивный вывод дерева, воспользуйтесь готовым решением - классом Walker_Nav_Menu. Он позволяет легко выстроить ровно тот HTML, который вам нужен.
    Ответ написан
    2 комментария
  • Можно ли загрузить base64 или blob в wordpress галерею?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Насколько мне известно, так не получится. Функция media_handle_upload() обрабатывает POST запрос, и принимает индекс из массива $_FILES. Далее она передает $_FILES['индекс'] по ссылке на функцию wp_handle_upload(), которая в свою очеред отправляет на _wp_handle_upload(), которая уже выполняет проверку конкретного загруженного файла во временной папке, валидирует его и перемещает в папку загрузок. После чего создает запись типа 'attachment' и пишет все необходимые данные и связи.

    Это что касается "что WP там делает под капотом". Что же касается вашей задачи - не совсем понятно что вы пытаетесь сделать и зачем. Если вы хотите хранить кропнутую картинку в БД в base64 / blob, вместо файловой системы и медиа-библиотеки, то зачем вам вообще media_handle_upload? Насколько я понял, у вас уже есть необходимые данные, осталось просто записать их в БД. Сделайте свою таблицу, пишите их туда и привязывайте внешним ключом к нужной записи (слайдеру, если я правильно вас понял).
    Ответ написан
    4 комментария
  • Как написать запрос в базу wordpress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    1. Получить ID постов в конкретной категории:
    $args = array(
        'post_type' => 'post', // изолируем нужный post type
        'post_status' => 'publish', // изолируем только опубликованные записи
        'category__in' => array( 15 ), // где 15 - ID вашей категории
        'posts_per_page' => -1, // забираем все посты, отвечающие требованиям
        'fields' => 'ids', // возвращаем только массив ID найденных записей
        'cache_results' => true, // кешируем полученные результаты
        'no_found_rows' => true, // не считаем общее количество найденных записей
        'update_post_meta_cache' => false, // не забираем и не кешируем метаданные для этих записей
        'update_post_term_cache' => false, // не забираем и не кешируем термины для этих записей
    );
    $posts_in_category = new WP_Query( $args );

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

    2. Получаем теги, которые используются данными постами (полученными выше):
    $args = array(
        'taxonomy' => 'post_tag', // изолируем нужную таксономию
        'object_ids' => $posts_in_category->posts, // получаем только теги, которые присвоеные объектам с этими ID
        'update_term_meta_cache' => false, // true|false - получать ли (и кешировать ли) метаданные терминов
    );
    $tags_in_posts = get_terms( $args );

    На выходе у вас будет массив тегов. Дополнительные параметры можете смотреть тут. Собственно, вместо get_terms() можете использовать WP_Term_Query.

    UPDATE:

    Допустил ошибку в коде, строчка 'object_ids' => $posts_in_category, должна быть 'object_ids' => $posts_in_category->posts, - ибо переменная будет содержать объект WP_Query, а уже свойство posts будет содержать ID найденных постов.

    Еще один важный нюанс и еще одна ошибка - если категорию включать с помощью параметра 'cat', то запрос по умолчанию будет выполнен с параметром 'include_children' => true, что нам не нужно, ибо исказит результат и включит ненужные посты. Переписал и этот фрагмент - вместо использования стандартного параметра 'cat' теперь используем 'category__in' - это включит только посты, которым назначена именно эта категория.

    Что касается количества выполненных запросов:

    WP_Query выполнит только 1 запрос:

    SELECT wp_posts.ID
    FROM wp_posts 
    LEFT JOIN wp_term_relationships
    ON (wp_posts.ID = wp_term_relationships.object_id)
    WHERE 1=1 
    AND ( wp_term_relationships.term_taxonomy_id IN (2) )
    AND wp_posts.post_type = 'post'
    AND ((wp_posts.post_status = 'publish'))
    GROUP BY wp_posts.ID
    ORDER BY wp_posts.post_date DESC


    В данном коде 2 = ID категории на моем тестовом сайте. На выходе получается Х постов, которым назначена именно эта категория.

    Далее, get_terms выполнит тоже всего 1 запрос:

    SELECT t.*, tt.*
    FROM wp_terms AS t 
    INNER JOIN wp_term_taxonomy AS tt
    ON t.term_id = tt.term_id
    INNER JOIN wp_term_relationships AS tr
    ON tr.term_taxonomy_id = tt.term_taxonomy_id
    WHERE tt.taxonomy IN ('post_tag')
    AND tr.object_id IN (19, 15, 13, 1)
    ORDER BY t.name ASC


    В данном коде 19, 15, 13, 1 - это и есть ID постов, которые мы получили первым запросом. Таким образом, будут получены только термины таксономии post_tag, которые назначены этим конкретным постам.
    Ответ написан
  • Сколько будет стоить сделать такой лендинг на вордпресс?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Простого примера "по ссылке" недостаточно, нужно видеть конкретный дизайн и ТЗ. Цена будет сильно колебаться в зависимости от конкретных деталей. Очень важно понимать точный объем работы "под капотом" - если клиент запросил WordPress, значит ему нужна возможность редактировать на этом лендинге все или только часть. Возможно, делать клоны и проводить A/B тестирование. Возможно еще какие-то фичи, которые не видны на фронте.

    Любой, кто озвучит какую-то цену без выяснения всех деталей, ткнет пальцем в небо. И, с вероятностью 99,99% эта оценка будет в итоге ошибочной.

    Also, на цену будет влиять стоимость работ конкретного исполнителя. Кто-то работает за $10/час, кто-то за $50/час. А также квалификация и опыт. У кого-то прикрутить форму заказа / звонка / обратной связи займет 30 минут, у кого-то - 3 дня задавать вопросы на Тостере, потому что "что-то пошло не так".
    Ответ написан
    Комментировать
  • Есть ли плагин для WP, показывающий статистику обращений к сайту?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    1. Писать подобные логи надо на уровне сервера, а не плагинами в базу WP.
    2. Для защиты от DDoS подключите CloudFlare, у них теперь эта защита даже на бесплатных аккаунтах есть
    Ответ написан
  • В какую директорию положить файл обработчик mail.php в wordpress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    1. Для пути лучше используйте абсолютный URL, надежнее будет.
    2. А вот это:
    if (isset($_POST['name'])) {$name = $_POST['name'];}
        if (isset($_POST['phone'])) {$phone = $_POST['phone'];}
        if (isset($_POST['formData'])) {$formData = $_POST['formData'];}

    вместе с вот этим:
    $message = "$formData<br> <b>Имя пославшего:</b> $name <br><b>Телефон:</b> $phone";

    вообще круто. Вы же слышали хоть что-то про санитизацию входящих данных? А то пишете подобное, а потом клиенты ко мне приходят со слезами на глазах "наш сайт взломали, сколько будет стоить почистить сайт от вирусов"... Я ж не резиновый, на всех не хватит. Почитывайте хоть иногда про безопасность.
    Ответ написан
    Комментировать
  • Права папки wp-content 777, чем опасно?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Не могу ставить/менять темы, плагины и прочее пока не установлю права 777

    Это означает, что владелец файлов и папок не имеет прав на запись, например, заливали от пользователя root или username, а исполняется все от www-data или другого юзера. Необходимо менять владельца, а не права.

    Насколько это безопасно?

    Совсем небезопасно. Давайте разберем коды прав, чтобы вы понимали как это работает:

    Каждая из 3х цифр отвечает за права:

    1. Пользователя
    2. Группы
    3. Всех желающих (world)

    Каждая цифра - это octal notation конкретных прав (rwx):

    Чтение (read)
    Запись (write)
    Исполнение (execute)

    Что означают конкретные цифры (и буквы):

    7	read, write and execute	rwx
    6	read and write	rw-
    5	read and execute	r-x
    4	read only	r--
    3	write and execute	-wx
    2	write only	-w-
    1	execute only	--x
    0	none	---


    Поэтому, 777 означают, что и владелец файла, и любой пользователь входящий в группу файла, и вообще кто угодно (1я, 2я и 3я цифры соответственно) имеют права "read, write and execute" - читать, писать в файл и исполнять его. Отсюда и опасность - вы разрешаете всем подряд запись в файлы.

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

    Правильные права для файлов - 644. Владелец может читать и писать (исполнять файлы не нужно), группа и мир могут только читать файлы (что и является важным с точки зрения безопасности).

    Для некоторых файлов права могут быть еще более жесткие, например wp-config.php достаточно чтобы был доступен для чтения и записи только пользователем, остальные не должны иметь доступа вообще (чтобы не видеть пароли, например) - тогда права выставляются 600 (владельцу можно читать и писать - 6, остальным доступ закрыт - 0).
    Ответ написан
    Комментировать
  • Как изменить постоянную ссылку с p=1?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Вы зачем-то привели объект WP_Post, поэтому предположу, что вы имеете в виду свойство guid этого объекта. Так вот, это не постоянная ссылка, это Global Unique Identifier, уникальный идентификатор записи.

    Из документации - The guid will appear to be a link, but should not be used as a link to the post.

    Постоянная ссылка генерируется на лету, cогласно настройкам раздела "Произвольные ссылки". Если же у вас пермалинки включены, но не работают - значит ваш конфиг хоста на сервере настроен без их поддержки. Уточните, что у вас - Apache, Nginx или что-то другое.
    Ответ написан
    1 комментарий
  • Как cделать поиск wordpress по meta_key?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Вот здесь готовое решение, к тому же доступно описано: https://adambalee.com/search-wordpress-by-custom-f...
    Ответ написан
    1 комментарий
  • Как сортируется выдача get_trems() по дефолту?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Функция get_terms() принимает те же аргументы, которые передаются в WP_Term_Query. Посмотреть их можно в конструкторе класса. Вот значения по умолчанию (цитаты из официальной документации, доступной бесплатно всем желающим):


    'orderby'
    (string) Field(s) to order terms by. Accepts term fields ('name', 'slug', 'term_group', 'term_id', 'id', 'description'), 'count' for term taxonomy count, 'include' to match the 'order' of the $include param, 'meta_value', 'meta_value_num', the value of $meta_key, the array keys of $meta_query, or 'none' to omit the ORDER BY clause. Defaults to 'name'.

    'order'
    (string) Whether to order terms in ascending or descending order. Accepts 'ASC' (ascending) or 'DESC' (descending). Default 'ASC'.


    То есть, по умолчанию, выдача сортируется по названиям терминов, от А до Я.
    Ответ написан
    Комментировать
  • Как защититься от хотлинка на виртуальном хостинге?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Если на входе стоит Nginx, то не важно то вы там делаете для статики (картинки, стили, скрипты) в .htaccess - запрос до Apache (и, соответственно, до обработки правил в .htaccess) не дойдет никогда. Для этого Nginx на входе и ставят.

    Hotlink protection на Nginx делается легко с помощью всего лишь одного правила для вашего виртуального хоста. Если хостер не дает вам возможности редактировать конфиг вашего виртуального хоста (или хотя бы его часть) - надо менять хостера. Другого способа решить вашу проблему я не вижу. Разве что CDN, как пишет Михаил (по сути, это еще один Nginx на входе перед всем остальным, но в этот раз вы можете редактировать конфиг, в отличие от вашего хостинга).
    Ответ написан
    Комментировать
  • Как сделать пагинацию на странице в wordpress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    В этих ваших интернетах уже стотыщмиллионов раз писано – никогда не используйте query_posts. Одна из главных причин - эта функция ломает пагинацию.

    Почитайте про хук pre_get_posts.
    Ответ написан
    Комментировать
  • Как получить язык (используя wpml) сохраняемого поста (в хуке save_post) wp?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Вместо локали попробуйте значения одной из констант WPML:

    ICL_LANGUAGE_CODE
    ICL_LANGUAGE_NAME
    ICL_LANGUAGE_NAME_EN

    Первая (код языка) думаю как раз то, что вам надо для проверок.
    Ответ написан