Функция получения списка url-ссылок из соответствующего поля ноды

Задача: есть нода определенного типа (например, "Article"). Нода имеет текстовое поле (имя поля,  к примеру, "field_links"), в которое пользователь может вставлять произвольное количество ссылок (по одному на поле, поле добавляется кнопкой "Добавить еще").

  1. Необходимо получить список этих ссылок со всех нод.
  2. Выбрать ссылки только с уникальным доменом и получить значение этого домена
  3. Для каждого домена получить заголовок страницы.

Решение задачи:

function _get_list_of_links() {
    // Массив, в который будем заносить каждый url, полученный из ноды типа "Article"
    $url = array();     
    // Массив, в который будем заносить каждый найденный уникальный домен
    $hosts = array();      
    // Возвращаемая переменная
    $output = '<ul class="list-of-links">';      
    // EntityFieldQuery - новый класс, введенный в Drupal 7
    // Позволяет получать набор сущностей (entities) с использованием условий (conditions)     
    $query = new EntityFieldQuery();
    // В условиях указываем тип сущности - node
    // Задаём тип ноды - Article 
    // Будем искать только опубликованные ноды (поле propertyCondition) 
    // Ноды, у которых нужное нам поле не заполнено, отбрасываем
    $query->entityCondition('entity_type', 'node')
        ->entityCondition('bundle', 'article')         
        ->propertyCondition('status', 1)         
        ->fieldCondition('field_links', 'value', 'NULL', '!=');              
    $result = $query->execute();      
    // Если найдена хоть одна нода, удовлетворяющая запросу, 
    // получаем список ID этих нод и загружаем их.
    // Иначе возвращаем пустую переменную     
    if (isset($result['node'])) {
        // Массив ID нод типа "Article", имеющих ссылки, 
        // введенные в поле field_links
        $nids = array_keys($result['node']); 
        // Функция entity_load позволяет массово загружать ноды         
        $nodes = entity_load('node', $nids);
    } else {
        return '';
    }
    
    foreach($nodes as $nid => $node) { 
        // Для каждой найденной ноды получаем значения, 
        // введенные в поле field_links
        $field_values = field_get_items('node', $node, 'field_links', $node->language);
        foreach($field_values as $value) { 
            // Ссылки добавляем в массив $url
            $url[] = $value['value'];
        }
    }
    // Число найденных ссылок
    $url_counts = count($url); 
    if (!empty($url)) {
        for ($i = 0; $i < $url_counts; $i++) { 
            // Функция parse_url разбивает ссылку на составляющие. 
            // Нам нужен только домен сайта.
            // Также добавляем префикс http://
            $host = 'http://' . parse_url($url[$i], PHP_URL_HOST); 
            // В массив $hosts добавляем только уникальные домены
            if (!in_array($host, $hosts)) {
                $hosts[] = $host;
            }
        }
    }
    // Число уникальных доменов
    $host_count = count($hosts);          
    for ($i = 0; $i < $host_count; $i++) {
    // Функция _get_title будет приведена ниже. 
    // С помощью неё получаем заголовок сайта
    $title = _get_title($hosts[$i]); 
    // Если не получилось найти заголовок присваиваем ему имя домена
    if (!isset($title)) $title = $hosts[$i];
        // Формируем список ссылок, указываем дополнительные аттрибуты
        $output .= '<li>'.l($title, $hosts[$i], array('external' => TRUE, 'attributes' => array('target' => '_blank'))).'</li>';
    }
    $output .= '</ul>';
    return $output;
}

Более подробно о классе EntityFieldQuery можно прочитать в статье How to use EntityFieldQuery.

Функция получения заголовка сайта на основе ссылки.

function _get_title($url){
    // Загружаем содержимое страницы
    $html = file_get_contents($url);
    if (strlen($html) > 0) {
        // С помощью регулярного выражения содержимое тега title передаём в переменную $title
        preg_match("/\<title\>(.*)\<\/title\>/", $html, $title);
        // Дабы избежать проблем с кодировкой используем функцию iconv.
        // Если преобразовать родную кодировку в UTF-8 не получилось, то функция вернёт пустой текст
        return iconv(mb_detect_encoding($title[1]), 'utf-8//TRANSLIT', $title[1]);
    }
}

Теги: