• Как удалить лишние атрибуты у изображений в 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' );
    Ответ написан
    Комментировать
  • Какой монитор подключить к Macbook Pro 15 MJLQ2?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Если глаза привыкли к ретине (а они ведь привыкли, правда?) и нужна качественная картинка - только 4k, в идеале даже 5k. Сам на вот таком 27", MBP тоже 15".

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

    Важно - 4к/5к надо поключать по miniDisplayPort - DisplayPort. HDMI даст только 30Гц, а это вообще неприемлемо. А при работе с DisplayPort кабелями могут быть проблемы с WiFi - ноут периодически теряет связь. Это древняя проблема, которую Apple не то что не решили, а по ходу еще и делают вид, что ее не существует. К счастью, лечится настройкой WiFi-роутера - придется перебрать каналы и вручную выбрать тот, на котором связь не будет пропадать.

    Также советую сразу присматривать подставку под ноут, желательно с охлаждением. Внешний монитор будет работать на дискретной видяхе, соответственно она всегда будет включена и встроенные вентиляторы бука будут жужжать постоянно на максимуме. При использовании хорошей внешней алюминиевой подставки с вентиляторами работать намного комфортнее. Она же (подставка) позволяет расположить ноут выше, что удобнее рядом с большим монитором.
    Ответ написан
    Комментировать
  • Какой Macbook выбрать для веб-программиста?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    У меня 15" MacBook Pro mid-2015:

    - 2.5 GHz Intel Core i7
    - 16 GB 1600 MHz DDR3
    - Intel Iris Pro 1536 MB
    - AMD Radeon R9 M370X 2 GB
    - SSD 512 GB

    Адский пепелац, который тянет все без каких-либо проблем, в том числе с подключенным внешним 4К монитором на 27", внешними же клавой, трекпадом и мышкой + несколькими HDD. Тот же PhpStorm шуршит волшебно, параллельно еще с тучей приложений и Chrome с овердофига вкладок.

    Из опыта эксплуатации понимаю, что в обозримом будущем менять его смысла нет - мощности хватает с запасом и еще долго будет хватать.
    Ответ написан
    1 комментарий
  • 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 комментария
  • Как получить список страниц с своей структурой?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Для всех древовидных данных WordPress предоставляет Walker'ы. Наиболее популярный (и наиболее часто используемый) - это Walker_Nav_Menu. Но есть также Walker_Page, который используется как раз в вашем случае.
    Ответ написан
    Комментировать
  • Где найти эти методы и свойства?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    +1 к ответу Max Medar, дополнительно - используйте полноценный IDE (например, PhpStorm). Иногда достаточно просто начать вводить логичное название функции, чтобы убедиться, что она внезапно существует:

    59f5cc2062599968188840.jpeg

    Ну и да, главный источник знаний - код ядра WP. Открываете и изучаете, пофайлово, или помодульно. Или как удобнее.
    Ответ написан
    Комментировать
  • Как задать классы для ссылок при выводе произвольного меню через 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 дня задавать вопросы на Тостере, потому что "что-то пошло не так".
    Ответ написан
    Комментировать
  • AWS или выделенный сервер?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Выделенный сервер - это одна фиксированная железка, с определенным фиксированным объемом ресурсов. Платите вы всегда одну и ту же сумму, доступные ресурсы можете использовать частично или полностью - не важно. Если начнется нехватка ресурсов (или, что чаще, какого-то одного конкретного ресурса - RAM, CPU, FS etc), будет большой головняк - искать возможность довоткнуть нужное железо или заменить, или вообще покупать новый сервер и переезжать и тд. В случае поломки железа сайт отваливается целиком, ибо сервер перестает работать.

    AWS, он же облачный виртуальный хостинг, дает множество преимуществ:

    - платите только за те ресурсы, которые вам реально нужны и вы использовали
    - при необходимости можно легко масштабировать ресурсы, при чем по отдельности - отдельно RAM, CPU и тд
    - файлы на block storage, при наличии бекапов в случае поломки какого-то железа downtime минимальный
    - можно (и для крупных проектов нужно) строить многосерверную архитектуру, разделяя балансировку нагрузки, фронт, статику, бек, базу (базы), АПИ, логгирование и мониторинг и тд и тп
    - можно практически все автоматизировать - развертывание в случае поломки железа, downsclaing / upscaling в случае изменения потребности ресурсов и тд

    В общем, это совершенно разные вещи. Что вам больше подходит - надо смотреть в конкретно вашей ситуации. AWS однозначно гибче, мощнее и тд. Но есть и минус - этим всем нужно управлять (и уметь это делать).

    Как альтернатива AWS, есть еще Digital Ocean. Тоже гибко и удобно, дешевле, сильно проще в управлении.
    Ответ написан
    Комментировать
  • Есть ли плагин для WP, показывающий статистику обращений к сайту?

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

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Инкрементальные бекапы с помощью rsync не пробовали?
    Ответ написан
    Комментировать
  • По каким причинам на фрилансе не всегда побеждает самая дешёвая ставка?

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

    Человек подсознательно ищет/выбирает товары и услуги под свой кошелек. Бедные покупают колбасу исключительно подешевле, и не особо смотрят кто производитель и из чего она сделана, и какая она на вкус. Обеспеченные покупают колбасу исключительно высшего сорта, обращая внимание на состав, производителя, дату производства (а не срок годности - чувствуете разницу?), вкусовые качества и тд. Именно благодаря этой особенности нашей психики процветают всякие "Премиум" и "ВИП" штуки. Именно этой особенностью часто пользуются недобросовестные ребята, предлагая какую-то хрень задорого под вывеской "Премиум" и жестко навариваясь на лохах, которые решили "шикануть" (то есть, являются wannabies - те кто хотят выглядеть круче чем они есть). На этой же особенности существуют подделки и китайские "лабутены". И еще очень много завязано.

    Оптимальный путь дзен - качать скилы и постепенно повышать цены, которые будут четко соответствовать уровню скилов. Тогда "ваш клиент" всегда будет. Проблемы начинаются, когда заявленная цена не соответствует качеству.
    Ответ написан
    Комментировать
  • В какую директорию положить файл обработчик 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).
    Ответ написан
    Комментировать