Интеграция с приложением «Контакты»

Содержание...

Приложение «Контакты» является системным приложением фреймворка и предоставляет инструменты для работы с пользователями бекенда и любыми другими контактами. Интеграция с «Контактами» позволяет любому приложению получить доступ к единой базе контактов Вебасиста.

База данных

Информация о контактах хранится в нескольких таблицах.

wa_contact — таблица с основной информацией о контакте
id — ID контакта в базе (auto_increment)
name — полное имя контакта, формируется при сохранении данных о контакте
firstname — имя
middlename — отчество
lastname — фамилия
title — обращение (например, гражданин, гражданка)
company — название компании
is_user — является ли пользователем бекенда Вебасиста, по умолчанию 0
login — логин пользователя бекенда
password — пароль для входа в бекенд
birthday — DATE, дата рождения
about — TEXT, произвольное текстовое описание контакта
photo — имя файла фотографии контакта
locale — локаль контакта, определяет язык, на котором будет показан интерфейс для этого контакта, например, ru_RU, en_US
timezone — часовой пояс контакта, например, Europe/Moscow

Служебные поля хранятся в этой же таблице:
create_datetime — дата и время создания контакта
create_app_id — APP_ID приложения, создавшего контакт
create_method — метод создания контакта (например, add - ручное добавление, import - импорт, form - через форму подписки и т.д.),
create_contact_id — ID контакта, создавшего контакт при ручном создании контакта

wa_contact_emails — таблица для хранения email-адресов контактов, у которых добавлено более одного адреса
id — сквозной ID email-адреса (auto_increment)
contact_id — ID контакта
email — адрес
ext — дополнительная информация, home - личный/домашний, work - рабочий и т.д.
sort — порядок отображения адресов контакта; email, у которого значение sort равно 0, считается основным (используется для рассылок уведомлений, авторизации и т.д.), остальные email-адреса считаются дополнительными
status — enum('unknown', 'confirmed', 'unconfirmed', 'unavailable') — статус адреса: неизвестно (например, добавили контакт вручную), подтвержден, не подтвержден, недоступен (при попытке отправить email, письмо вернулось)

wa_contact_data — таблица для хранения произвольных дополнительных данных (телефон, адрес и т.д.)
id — сквозной ID записи
contact_id — ID контакта
field — строковый идентификатор поля, например phone, url и т.д.
ext — дополнительная информация (home - домашний, work - рабочий и т.д.)
value — VARCHAR(255) — значение поля
sort — порядок отображения поля в форме с информацией о контакте

В этой же таблице хранятся композитные поля (поля состоящие из нескольких подполей). Например, адрес (подполя указываются через двоеточие):
address:country
address:city
address:state
address:street
address:zip

Описание полей контакта

Все поля, которые могут быть заданы для контакта, описываются в файле wa-system/contact/data/field.php.
Например, так выглядит описание поля «телефон» (фрагмент файла field.php):

new waContactPhoneField('phone', 'Phone', array(
    'multi' => true, // у одного контакта может быть несколько телефонов
    'ext'   => array( // набор возможных дополнений «суффиксов»
        'work'   => 'Work',
        'mobile' => 'Mobile',
    	'home'   => 'Home',
    )
)),

Чтобы добавить новое поле для контакта, достаточно выполнить следующее:

  1. добавить его описание в файл wa-config/apps/contacts/custom_fields.php, например, поле «автомобиль»:
    <?php
    
    return array(
        new waContactStringField(
            'car',
            array(
                'en_US' => 'Car',
                'ru_RU' => 'Автомобиль',
                array()
            )
        ),
    );
    
  2. включить это поле, добавив в конец файла wa-config/apps/contacts/person_fields_order.php строку
    'car' => array()

    Если этот файл отсутствует, создайте его, полностью скопировав в него содержимое файла wa-system/contact/data/person_fields_default.php.

    <?php
    
    return array(
        // ... - тут все остальные поля
        'car' => array()
    );

Создание и редактирование контакта

Для работы с контактом необходимо использовать класс waContact. В этом классе реализованы все необходимые методы. Изменять и читать данные контакта напрямую из БД категорически не рекомендуется. Класс waContact используется очень просто:

// создание экземпляра контакта

// новый контакт
$contact = new waContact();

// существующий контакт
$contact = new waContact($id);

// изменение данных контакта
$contact[$field] = $value;

//Например, задать email можно так:
$contact['email'] = 'test@domain.com';

//или так
$contact['email'] = array(
    'value'  => 'test@webasyst.com', 
    'ext'    => 'work',
    'status' => 'confirmed'
);

Несколько email-адресов можно задать аналогично.

$contact['email'] = array(
    'email1@domain.com',
    'email2@domain.com'
);

Имейте ввиду, что при таком задании адресов все существующие адреса контакта будут удалены. Если нужно добавить новый адрес к уже существующим, то это можно сделать с помощью метода add:

$contact->add('email', 'newemail@domain.com');

Чтобы сохранить все изменения в БД, необходимо вызвать метод save():

$contact->save();

Метод возвращает 0, если все успешно, иначе возвращает массив ошибок:

if ($errors = $contact->save()) {
    // массив ошибок, которые произошли при сохранении контакта
}

В метод save() можно также передать массив данных, которые необходимо сохранить, например:

$contact->save(array(
    'phone' => array(
        'value' => '4354235',
        'ext'   => 'work'
    ),
    'email' => 'test@domain.com'
));

Удаление значения

unset($contact['email']); 
$contact->save();
// все email-адреса контакта удалены

Получение данных контакта

$contact = new waContact($id);

$emails = $contact['email'];
$emails = $contact->get('email');

Поскольку у контакта может быть несколько email-адресов, то $emails будет содержать массив значений в таком виде:

array(
    0 => array (
       [value]  =>email1@domain.com,
       [ext]    => home,
       [status] => unknown
    ),
    1 => array (
       [value]  => email2@domain.com,
       [ext]    => work,
       [status] => confirmed
    ),
);

Это касается всех множественных полей, в которых возможны несколько значений.

В ситуациях, в которых требуется получить только одно значение поля (например, получить email для отправки уведомления), следует поступить так:

// первый из email-адресов контакта
$email = $contact->get('email', 'default');

Имя контакта:

$name = $contact['name'];
//или так
$name = $contact->getName();

ID контакта:

$id = $contact['id'];
//или так
$id = $contact->getId();

Композитные поля

Композитными полями называются поля, которые состоят из нескольких подполей. Например, адрес состоит из индекса, страны, области, города, улицы.

$contact->get('address');

Array
(
    [0] => Array
        (
            [data] => Array
                (
                    [city]    => Москва
                    [country] => rus
                    [street]  => Крымский Вал, д. 3, стр. 2
                )
    
            [ext]   => work
            [value] => Крымский Вал, д. 3, стр. 2, Москва, Российская Федерация
        )

)

В value передается значение, готовое к отображению (вывод запрограммирован в классе, который описывает тип поля). В data — массив значений подполей.

Изменять такие поля нужно с осторожностью. Например, изменить город в первом из адресов контакта правильно так:

$address = $contact->get('address');
$address[0]['data']['city'] = 'Москва';
$contact->save(array('address' => $address));

Добавить еще один адрес:

$contact->add(
    'address',
    array(
        'city'    => 'Москва',
        'country' => 'rus'
    )
);
$contact->save();

Объект текущего пользователя (wa()->getUser(), или $this->getUser() — внутри экшенов и контроллеров) является также экземпляром класса waContact. Поэтому все описанное выше применимо и к нему.

Примеры:
//получить имя текущего пользователя
$this->getUser()->getName();

//получить основной email-адрес
$this->getUser()->get('email', 'default');