Исключение iPad из wp_is_mobile

16 сент. 2013 г., 20:07:59
Просмотры: 21.8K
Голосов: 12

Я столкнулся с очень раздражающей проблемой. Я создал свой сайт с медиа-запросами и is_mobile (наивно полагая, что is_mobile будет соответствовать меньшим экранам). После тестирования выяснилось, что iPad все портит (хотя, на самом деле, это я накосячил).

Все мои проблемы можно было бы легко решить, если бы удалось исключить iPad из функции wp_is_mobile. Как мне переписать эту функцию?

function wp_is_mobile() {
    static $is_mobile;

    if ( isset($is_mobile) )
        return $is_mobile;

    if ( empty($_SERVER['HTTP_USER_AGENT']) ) {
        $is_mobile = false;
    } elseif ( 
        // многие мобильные устройства (все iPhone, iPad и т.д.)
        (strpos($_SERVER['HTTP_USER_AGENT'], 'Mobile') !== false 
        && strpos($_SERVER['HTTP_USER_AGENT'], 'iPad') === false) // исключаем iPad
        || strpos($_SERVER['HTTP_USER_AGENT'], 'Android') !== false
        || strpos($_SERVER['HTTP_USER_AGENT'], 'Silk/') !== false
        || strpos($_SERVER['HTTP_USER_AGENT'], 'Kindle') !== false
        || strpos($_SERVER['HTTP_USER_AGENT'], 'BlackBerry') !== false
        || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera Mini') !== false ) {
            $is_mobile = true;
    } else {
        $is_mobile = false;
    }

    return $is_mobile;
}

Как мне это изменить?

0
Все ответы на вопрос 4
4
17

Ответ t f заставил меня задуматься. На самом деле, я могу использовать основную функцию и адаптировать её по своему усмотрению, просто поместив всё в новую функцию. Вот что получилось:

function my_wp_is_mobile() {
    static $is_mobile;

    if ( isset($is_mobile) )
        return $is_mobile;

    if ( empty($_SERVER['HTTP_USER_AGENT']) ) {
        $is_mobile = false;
    } elseif (
        strpos($_SERVER['HTTP_USER_AGENT'], 'Android') !== false
        || strpos($_SERVER['HTTP_USER_AGENT'], 'Silk/') !== false
        || strpos($_SERVER['HTTP_USER_AGENT'], 'Kindle') !== false
        || strpos($_SERVER['HTTP_USER_AGENT'], 'BlackBerry') !== false
        || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera Mini') !== false ) {
            $is_mobile = true;
    } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Mobile') !== false && strpos($_SERVER['HTTP_USER_AGENT'], 'iPad') == false) {
            $is_mobile = true;
    } elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'iPad') !== false) {
        $is_mobile = false;
    } else {
        $is_mobile = false;
    }

    return $is_mobile;
}
16 сент. 2013 г. 22:39:23
Комментарии

Всегда хорошо находить собственные решения, так что +1 за это. Однако я также обновил свой ответ. У меня была глупая опечатка: я проверял ===, тогда как должен был проверить !== — не знаю, как это произошло, но теперь я это исправил. Так что мой ответ должен работать тоже — что я ни в коем случае не говорю, чтобы вы его приняли! Просто по сути наши ответы/функции делают одно и то же — поэтому я просто хотел найти (и исправить) то, что было не так.

tfrommen tfrommen
16 сент. 2013 г. 23:44:45

@tf Именно об этом я и говорил в своем комментарии! Но я собираюсь принять свой собственный ответ, потому что знаю, что он работает, а ваш код я не тестировал. Я не хочу, чтобы кто-то прочитал это и воспользовался вашим ответом, если я его не проверил. Я чувствую некоторую ответственность за эту ветку. Надеюсь, вы понимаете. Но все равно спасибо за старания!

Bram Vanroy Bram Vanroy
17 сент. 2013 г. 11:43:12

Ребята, вам вообще удалось протестировать это вживую на iPad? Я прямо сейчас пытаюсь, но без успеха — iPad Air, локально.

kevin kevin
8 янв. 2014 г. 22:18:29

@kevin протестировал это на iPAD 3, и это сработало.

Bram Vanroy Bram Vanroy
8 янв. 2014 г. 22:25:56
0

Я знаю, что это старый пост, но хотел обновить его, показав правильный способ реализации предыдущих решений в WordPress. Начиная с версии 4.9.0, вместо создания дополнительной функции следует фильтровать результат wp_is_mobile(). Вот так:

function myprefix_exclude_ipad( $is_mobile ) {
    if (strpos($_SERVER['HTTP_USER_AGENT'], 'iPad') !== false) {
        $is_mobile = false;
    }
    return $is_mobile ;
}
add_filter( 'wp_is_mobile', 'myprefix_exclude_ipad' );

ОДНАКО по-настоящему правильным решением было бы переписать тему, чтобы она корректно работала на планшетах. Ведь существуют и другие производители планшетов помимо Apple.

19 дек. 2018 г. 02:21:20
4

Вы также можете использовать регулярно обновляемый класс Mobile Detect PHP для создания пользовательской функции обнаружения мобильных устройств, исключая планшеты (включая iPad). На момент написания этого ответа репозиторий на Github был последний раз обновлен 3 месяца назад для включения обнаружения новых планшетов Samsung.

Предполагая, что вы разместили необходимый файл в директории /includes/ вашей темы, вы можете добавить этот код в ваш functions.php:

require_once(get_template_directory() . '/includes/Mobile_Detect.php');

function md_is_mobile() {

  $detect = new Mobile_Detect;

  if( $detect->isMobile() && !$detect->isTablet() ){
    return true;
  } else {
    return false;
  }

}

Затем используйте функцию md_is_mobile() как замену для wp_is_mobile().

7 февр. 2015 г. 11:23:44
Комментарии

Разве это решение не зависит от установки плагина, содержащего класс Mobile Detect?

Brad Dalton Brad Dalton
7 февр. 2015 г. 15:35:03

Зависимость от класса Mobile Detect обрабатывается первой строкой приведённого блока кода; дополнительные плагины не требуются. Стоит отметить, что существуют плагины для WordPress на основе этого класса, например WP Mobile Detect, но он не обновлялся почти 2 года, поэтому лично я предпочитаю использовать PHP-класс напрямую, который, судя по всему, активно разрабатывается.

Astrotim Astrotim
9 февр. 2015 г. 03:52:39

Справедливый ответ, однако вам необходимо установить файл Mobile_Detect.php, который я называю плагином.

Brad Dalton Brad Dalton
9 февр. 2015 г. 11:00:25

Это вполне справедливо!

Astrotim Astrotim
10 февр. 2015 г. 04:47:45
7

Я немного переписал (и, на мой взгляд, оптимизировал) вашу функцию:

function wp_is_mobile() {
    static $is_mobile;

    if (isset($is_mobile))
        return $is_mobile;

    if (
        ! empty($_SERVER['HTTP_USER_AGENT'])

        // пропускаем, если это iPad
        && false === strpos($_SERVER['HTTP_USER_AGENT'], 'iPad')

        // все остальные мобильные устройства
        && (
            false !== strpos($_SERVER['HTTP_USER_AGENT'], 'Mobile')
            || false !== strpos($_SERVER['HTTP_USER_AGENT'], 'Android')
            || false !== strpos($_SERVER['HTTP_USER_AGENT'], 'Silk/')
            || false !== strpos($_SERVER['HTTP_USER_AGENT'], 'Kindle')
            || false !== strpos($_SERVER['HTTP_USER_AGENT'], 'BlackBerry')
            || false !== strpos($_SERVER['HTTP_USER_AGENT'], 'Opera Mini')
        )
    ) $is_mobile = true;
    else $is_mobile = false;

    return $is_mobile;
}

// РЕДАКТИРОВАНИЕ:

Хорошо, ещё раз...

Напишем новую функцию, которая внутри использует основную функцию и расширяет её:

function my_wp_is_mobile() {
    if (
        ! empty($_SERVER['HTTP_USER_AGENT'])

        // пропускаем, если это iPad
        && false !== strpos($_SERVER['HTTP_USER_AGENT'], 'iPad')
    ) return false;
    return wp_is_mobile();
} // function my_wp_is_mobile

Теперь вы можете использовать вашу новую функцию my_wp_is_mobile где угодно.

16 сент. 2013 г. 20:52:21
Комментарии

Значит, я могу просто поместить это в файл functions.php, и он автоматически перезапишет основную функцию?

Bram Vanroy Bram Vanroy
16 сент. 2013 г. 21:04:54

Упс, извините, моя ошибка — я никогда не использовал это (и поэтому не знал, что это ядро WP). Поскольку функция не является заменяемой, вы не можете просто поместить это в ваш файл functions.php. Я обновлю свой ответ через минуту...

tfrommen tfrommen
16 сент. 2013 г. 21:08:12

Кажется, это не работает. Но разве user agent для iPad не должен возвращать true?

Bram Vanroy Bram Vanroy
16 сент. 2013 г. 21:37:45

Хм? Я понял так, что ты хочешь исключить iPads из списка мобильных устройств - как это делает wp_is_mobile...? Так что именно не работает (как ты хотел бы)?

tfrommen tfrommen
16 сент. 2013 г. 22:07:03

К сожалению, у меня самого нет iPad, поэтому я полагаюсь на информацию от друзей. Но сейчас у меня есть дизайн, который загружает сайдбар, если user agent "!is_mobile" (не мобильный), но для iPad это не нужно, так как его разрешение достаточно большое. Друзья говорят мне, что даже при использовании if(!my_wp_is_mobile() ) сайдбар все равно не отображается. Из чего я делаю вывод, что функция не работает.

Bram Vanroy Bram Vanroy
16 сент. 2013 г. 22:10:08

И что я имел в виду в своем комментарии: я думал, что функция проверяет "если user agent НЕ пустой И если ЛОЖЬ, что user agent - это iPad" возвращает false. Но мне кажется, мне нужно "если user agent НЕ пустой и если ИСТИНА, что user agent - это iPad"? Возможно, это связано с тем, что ты запускаешь основную функцию ядра после кастомной функции? И тогда $_SERVER['HTTP_USER_AGENT'], 'Mobile') вернет true для iPad.

Bram Vanroy Bram Vanroy
16 сент. 2013 г. 22:14:05

Разобрался (см. мой собственный ответ). Все равно спасибо за идеи!

Bram Vanroy Bram Vanroy
16 сент. 2013 г. 22:39:38
Показать остальные 2 комментариев