Задать вопрос
  • Как правильно избавиться от дублирования при описании структуры массива?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Если это нужно только для подсказок в PhpStorm, то я бы рекомендовал использовать плагин deep-assoc-completion и не заморачиваться с docblock.
    Ответ написан
    2 комментария
  • Почему не устанавливаются cookie в Wordpress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Из документации (жирным выделил то, что важно):
    setcookie() задает cookie, которое будет передано клиенту вместе с другими HTTP-заголовками. Как и любой другой заголовок, cookie должны передаваться до того как будут выведены какие-либо другие данные скрипта (это ограничение протокола). Это значит, что в скрипте вызовы этой функции должны располагаться до остального вывода, включая вывод тегов и , а также пустые строки и пробельные символы.

    Из-за этого не работает в footer.php. Если бы у вас был включен режим отладки и вывод ошибок, то вы бы увидели что-то типа:
    Warning: Cannot modify header information - headers already sent by (output started at /Users/Ihor/Code/playground/wp-includes/class.wp-styles.php:242) in /Users/Ihor/Code/playground/wp-content/themes/playground/footer.php on line 8

    Далее, пример с хуком init работает, но есть 2 нюанса. Во-первых, у вас ошибка - константы DAYS_IN_SECONDS не существует, должна быть DAY_IN_SECONDS. Далее, опять идем в документацию по поводу этого параметра (жирным выделил то, что важно):
    expires
    Время, когда срок действия cookie истекает. Это метка времени Unix, то есть количество секунд с начала эпохи. Другими словами, желательно задавать это время с помощью функции time(), прибавляя время в секундах, через которое срок действия cookie должен истечь. Либо можно воспользоваться функцией mktime(). time()+60*60*24*30 установит срок действия cookie 30 дней. Если задать 0 или пропустить этот аргумент, срок действия cookie истечет с окончанием сессии (при закрытии браузера).

    На языке кода это будет:
    function my_setcookie_example()
    {
    	setcookie(
    		'testing',
    		'123',
    		time() + 30 * DAY_IN_SECONDS, // вот так должно быть
    		COOKIEPATH,
    		COOKIE_DOMAIN
    	);
    }
    add_action( 'init', 'my_setcookie_example' );

    Во-вторых, из той же документации (жирным выделил то, что важно):
    После передачи клиенту cookie станут доступны через массив $_COOKIE при следующей загрузке страницы. Значения cookie также есть в $_REQUEST.

    То есть, ваше var_dump($_COOKIE['testing']); сработает только после перезагрузки, а при первой попытке - NULL и:
    Notice: Undefined index: testing in /Users/Ihor/Code/playground/wp-content/themes/playground/functions.php on line 134
    .

    RTFM.
    Ответ написан
  • Как при отсутствии thumbnails в записи, выводить thumbnail заглушку?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Ответ Вадим Кот полностью подходит, если надо в конкретном месте шаблона разово запилить. Но если это должно быть как стандартное поведение везде, где есть post thumbnails, а сторонний плагин ставить не хочется, то лучше написать свою функцию. У меня она среди прочих полезных лежит в mu-plugin'е, но можно и в functions.php:
    /**
     * Display native post thumbnail or a fallback image.
     *
     * @param  string  $size
     * @param  string  $attr
     */
    function the_post_thumbnail_fallback( $size = 'post-thumbnail', $attr = '' )
    {
    	if ( has_post_thumbnail() ) :
    		echo get_the_post_thumbnail( null, $size, $attr );
    
    	else :
    		$post_thumbnail_id = get_option( 'default_post_thumbnail' );
    
    		$html = wp_get_attachment_image( $post_thumbnail_id, $size, false, $attr );
    
    		/**
    		 * Filters the post thumbnail HTML.
    		 *
    		 * @param  string  $html  The post thumbnail HTML.
    		 * @param  int  $post_id  The post ID.
    		 * @param  string  $post_thumbnail_id  The post thumbnail ID.
    		 * @param  string|array  $size  The post thumbnail size. Image size or array of width and height values (in that order). Default 'post-thumbnail'.
    		 * @param  string  $attr  Query string of attributes.
    		 * @since 2.9.0
    		 */
    		echo apply_filters( 'post_thumbnail_html', $html, null, $post_thumbnail_id, $size, $attr );
    
    	endif;
    }

    В шаблонах просто используем эту функцию вместо the_post_thumbnail(), включая необходимые параметры (размер и тд):
    <header class="post-header">
        <h1 class="post-title">
            <?php the_title(); ?>
        </h1>
    
        <div class="post-thumbnail">
            <?php the_post_thumbnail_fallback(); ?>
        </div>
    </header>

    В самой функции the_post_thumbnail_fallback() обратите внимание на строчку
    $post_thumbnail_id = get_option( 'default_post_thumbnail' );

    Сама картинка загружена через медиабиблиотеку, ее ID хранится в wp_options. У меня это реализовано в настройках (как и в плагине, на который ссылается Вадим Кот), но можно захардкодить ID прямо в этой функции. HTML создается нативной wp_get_attachment_image(), идентично тому что создаст the_post_thumbnail() потому что она использует эту же функцию.

    Также здесь у нас сохранен фильтр post_thumbnail_html, с помощью которого сторонние плагины могут модифицировать html-код тега img - а это могут быть вполне полезные фичи - SEO, css-классы (например для lazyload), responsive и тд.
    Ответ написан
    Комментировать
  • Автогенерация страниц?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Конечно можно - wp_insert_post() и вперед. Есть плагины-импортеры на все вкусы. Если у вас текст уже есть в какой-то БД, то проще всего написать скрипт-миграцию, который пройдется по этой БД и создаст необходимые страницы с помощью вышеупомянутой функции. Можно даже в метаданных хранить внешний ID контента этой страницы, и по расписанию сверять с оригинальной базой, при необходимости делать обновления или новые тексты заливать в новые страницы. Все реализуемо.
    Ответ написан
    1 комментарий
  • Можно ли поставить платную тему Wordpress с themeforest сперва на локальный сервер, а потом уже на хостинг?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Да, можно. Лицензия позволяет и вообще это нормально. Как минимум есть локалка, стейдж и прод.
    Ответ написан
    3 комментария
  • Как вывести категории на мультиязычном сайте?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Я с Polylang давно не работал, может там апишка поменялась уже, но в целом смысл в том, чтобы вместо parent => 21 (фиксированный ID на одном языке) передавать parent => {ID отфильтрованный через Popylang}. Вот так:

    $categories = get_categories([
      'taxonomy'     => 'category',
      'type'         => 'post',
      'child_of'     => '',
      'parent'       => pll_get_term(21),
      'orderby'      => 'name',
      'order'        => 'ASC',
      'hide_empty'   => 0,
      'hierarchical' => 1,
      'exclude'      => '',
      'include'      => '',
      'number'       => 0,
      'pad_counts'   => false,
    ]);

    https://polylang.wordpress.com/documentation/docum...
    Ответ написан
  • Как исправить ошибку в валидации сайта на wordpress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Тег link может быть использован только внутри document head, а у вас он в document body.

    И это ошибка валидации HTML, к WordPress это не имеет никакого отношения, уберите ненужные теги.
    Ответ написан
    Комментировать
  • Как убрать посты с статусом (удалены или черновик) общего списка?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Вы выборку делаете по таблице wp_postmeta. В этой таблице хранится только ID записи. Чтобы узнать (и отфильтровать) по ID статус этой записи, используйте JOIN с таблицей wp_posts:
    SELECT post_id, post_status, meta_value
    FROM wp_postmeta
    JOIN wp_posts
    ON wp_postmeta.post_id=wp_posts.id
    WHERE meta_key = 'data-provedeniya' AND post_status = 'publish'
    Ответ написан
    1 комментарий
  • Получить доступ к БД из своего класса WordPress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Ваш код выполняется ВНЕ контекста WP, поэтому global $wpdb всегда будет возвращать null - ибо в вашем текущем глобальном scope (вашего кастомного кода который никак не связан с WP) данной переменной нет. Чтобы она там появилась, вам нужно подгрузить минимально необходимую часть ядра WP:
    define( 'SHORTINIT', true );
    require( '/path/to/wp-load.php' );
    Ответ написан
    1 комментарий
  • Как выводить деньги из пейпала в Украине?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    1. Благотворительным или нет - несущественно.
    2. В Украине палка работает только в одну сторону, вывести оттуда деньги нельзя, а в первую очередь - нельзя получить от кого-то.
    3. Ищите альтернативные методы - TransferWise, Skrill / Neteller и тому подобное. Ну или если юрлицо/ФОП, то можно утилизировать эквайринг/LiqPay, у них форма приема платежей модная-молодежная, работает отлично.
    Ответ написан
  • Вывод предупреждения, что для работы собственного плагина необходимо наличие плагина стороннего. Как реализовать?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    ACF сам себя проверяет вот таким образом:
    if ( ! class_exists( 'ACF' ) ) :
        // ...
    endif;

    И это наиболее адекватный способ. А вот is_plugin_active() я бы не советовал использовать - ACF может работать как обычная PHP-библиотека, установленная с помощью того же Composer, и тогда она не будет в списке плагинов.
    Ответ написан
    7 комментариев
  • Как в PhpStorm отключить автоподстановку кавычек?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    5d36ee408b478213953106.jpeg

    У меня прекрасно работает вот это:

    можно ли настроить как в саблайме — выделяешь текст, нажимаешь кавычку, он выделяет слово кавычками

    А по поводу вот этого желательно бы увидеть видео:

    Иногда в каких то запутанных конструкциях с экранированием phpstorm начинает вести себя неадекватно — ставишь кавычку в одном месте, а он ставит её в другом, ты стираешь, пытаешься опять поставить где тебе надо, он удаляет и ставит в третьем. Потом вроде успокаивается, даёт мне всё прописать как надо, я нажимаю сохранить...х*як...опять перемешались кавычки.
    Ответ написан
    Комментировать
  • Как вывести все изображения при помощи wp_get_attachment_link?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Поле Gallery в ACF возвращает массив с данными картинок. По массиву следует проходить циклом. Примеры циклов есть в документации.

    зы: Certificates пишется через C а не S.
    Ответ написан
    Комментировать
  • Возможно ли для произвольного типа записи сделать отдельную таблицу?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    1. Нет (*)
    2. Зачем?

    (*) - в принципе можно, но это большой кусок работы, к тому же он вполне может сломать 3rd-party функциональность.
    Ответ написан
  • Как верстать под wp?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Верстка под WP по сути укладывается всего в несколько отличий от верстки под что либо еще:

    1. В некоторых местах (body, меню, обертки страниц/записей и тд) WP генерит свой список классов. Его можно и нужно использовать, если тема предназначена на продажу или в репозиторий на .org, предполагается что ее будут крутить/развивать под свои задачи. Если для себя / для клиента, то можно не использовать, но как минимум с меню придется на бекенде несколько правок сделать.
    2. Контент, который редактируется в редакторе (старый TinyMCE или новый Gutengerg) либо лишен классов по умолчанию (тогда стучимся по классу контейнера), либо как разработчики намудрят (Gutenberg, всякие конструкторы страниц). В принципе, можно полностью под себя сделать с Gutenberg, но это дополнительные временные расходы.
    3. Статика (скрипты, стили) подключается из PHP, картинки и другие файлы - как правило тоже, через медиа-библиотеку.

    Иногда что-то по мелочи попадается, но в целом - это все.
    Ответ написан
  • Какие существуют IDE, написанные на С++ и/или Python?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Во-первых, саблайм быстрый не потому что питон, а потому что он всего лишь текстовый редактор, а не IDE.
    Во-вторых, все IDE от JetBrains условно медленные не потому что джава, а потому что это мощные IDE.
    Логику улавливаете?

    ЗЫ: Ну а Javascript / Electron это другая песня, оно в принципе норм, если есть ресурсы.
    Ответ написан
    Комментировать
  • Как использовать VPN на MAC OS?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Бери Windscribe (рефссылка), у них больше всего бесплатного трафика и цены адекватные если его не хватает.
    Ответ написан
    1 комментарий
  • Что делать в случае "холодного кэша" в час пик?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Работу с кешем нужно строить по 1 из 2 путей:

    1. Prime cache - ресурсоемкий запрос выполняется по установленному вами расписанию/событию и обновляет кеш, пользователь всегда получает данные только из кеша.

    2. Serve stale - выполнение ресурсоемкого запроса и обновление кеша идет параллельным процессом, в это время пользователи все еще получают предыдущие (пусть и менее актуальные) данные. Опять же, пользователь всегда получает данные только из кеша.
    Ответ написан
  • Как лучше хранить изображений? Одна папка или много?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Это называется "отношение 1 к многим", оно же one to many, оно же 1:n. На уровне базы данных выглядит так:

    Таблица tasks:
    - id
    - ...

    Таблица photos:
    - id
    - task_id (foreign key)
    - ...

    Все фотографии для конкретного задания получаются запросом:
    SELECT * FROM photos WHERE task_id=X

    В каких папках их хранить на самом диске - вопрос отдельный и по большому счету несущественный.
    Ответ написан
    6 комментариев
  • Как решить правильно простенькую задачку по php?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    // По вашему коду:
    $source_string = 'abcdefghijklmnopqrstuvwxyz';
    $string_randomized = str_shuffle($source_string); // Перетасовали буквы внутри строки
    echo substr($string_randomized, 0, 6); // Вывели первые 6, без повторений и каждый раз после str_shuffle - уникально-рандомно (относительно, но задача именно этого и требует)
    
    // По красоте:
    $characters = 'abcdefghijklmnopqrstuvwxyz';
    echo substr(str_shuffle($characters), 0, 6);
    
    // Тестируем в psych:
    >>> $characters = 'abcdefghijklmnopqrstuvwxyz';
    => "abcdefghijklmnopqrstuvwxyz"
    >>> echo substr(str_shuffle($characters), 0, 6);
    fzpvad
    >>> echo substr(str_shuffle($characters), 0, 6);
    bzeiyj
    >>> echo substr(str_shuffle($characters), 0, 6);
    pgkuaq
    >>> echo substr(str_shuffle($characters), 0, 6);
    otjszx
    >>> echo substr(str_shuffle($characters), 0, 6);
    zjwaox
    >>> echo substr(str_shuffle($characters), 0, 6);
    rxuhnv
    >>> echo substr(str_shuffle($characters), 0, 6);
    rihoec
    >>> echo substr(str_shuffle($characters), 0, 6);
    uwdfgn
    >>>
    Ответ написан
    5 комментариев