Ejemplo n.º 1
0
 public function updateLastTime($force = false)
 {
     $time = $this->storage->read('user_last_datetime');
     if (!$time || $force || $time == '0000-00-00 00:00:00' || time() - strtotime($time) > 120) {
         try {
             $login_log_model = new waLoginLogModel();
             $last_activity = $login_log_model->getCurrent($this->id);
         } catch (waDbException $e) {
             if ($e->getCode() == 1146) {
                 waSystem::getInstance()->getAuth()->clearAuth();
                 header("Location: " . wa()->getConfig()->getBackendUrl(true));
                 exit;
             }
         }
         $contact_model = new waContactModel();
         $contact_info = $contact_model->getById($this->id);
         $auth = waSystem::getInstance()->getAuth();
         if (!$auth->checkAuth($contact_info)) {
             header("Location: " . wa()->getConfig()->getRequestUrl(false));
             exit;
         }
         if (!$contact_info || waSystem::getInstance()->getEnv() == 'backend' && !$contact_info['is_user']) {
             waSystem::getInstance()->getAuth()->clearAuth();
             header("Location: " . wa()->getConfig()->getBackendUrl(true));
             exit;
         } else {
             $this->setCache($contact_info);
         }
         if (!$time) {
             $time = $contact_info['last_datetime'];
         }
         if (!$last_activity) {
             $login_log_model->insert(array('contact_id' => $this->id, 'datetime_in' => date("Y-m-d H:i:s"), 'datetime_out' => $force == 'logout' ? date("Y-m-d H:i:s") : null));
             // TODO: insert record in waLog
         } else {
             if ($force == 'logout') {
                 $login_log_model->updateById($last_activity['id'], array('datetime_out' => date("Y-m-d H:i:s")));
             } elseif ($last_datetime = strtotime($time)) {
                 if (time() - $last_datetime > self::$options['activity_timeout']) {
                     $login_log_model->updateById($last_activity['id'], array('datetime_out' => $time));
                     $login_log_model->insert(array('contact_id' => $this->id, 'datetime_in' => date("Y-m-d H:i:s"), 'datetime_out' => null));
                     // TODO: insert record in waLog
                 }
             }
         }
         $t = date("Y-m-d H:i:s");
         $contact_model->updateById($this->id, array('last_datetime' => $t));
         $this->storage->write('user_last_datetime', $t);
     }
 }
Ejemplo n.º 2
0
 public static function getStatusByInfo($info)
 {
     $timeout = self::$options['online_timeout'];
     // in sec
     if (isset($info['last_datetime']) && $info['last_datetime'] && $info['last_datetime'] != '0000-00-00 00:00:00') {
         if (time() - strtotime($info['last_datetime']) < $timeout) {
             $m = new waLoginLogModel();
             $datetime_out = $m->select('datetime_out')->where('contact_id = i:0', array($this->id))->order('id DESC')->limit(1)->fetchField();
             if (!$datetime_out) {
                 return 'online';
             } else {
                 return 'offline';
             }
         }
     }
     return 'offline';
 }
Ejemplo n.º 3
0
 /**
  * Get data for contacts in this collection.
  * @param string|array $fields
  * @param int $offset
  * @param int $limit
  * @return array [contact_id][field] = field value in appropriate field format
  * @throws waException
  */
 public function getContacts($fields = "id", $offset = 0, $limit = 50)
 {
     $sql = "SELECT " . $this->getFields($fields) . " " . $this->getSQL();
     $sql .= $this->getGroupBy();
     $sql .= $this->getHaving();
     $sql .= $this->getOrderBy();
     $sql .= " LIMIT " . ($offset ? $offset . ',' : '') . (int) $limit;
     //header("X-SQL-". mt_rand() . ": ". str_replace("\n", " ", $sql));
     $data = $this->getModel()->query($sql)->fetchAll('id');
     $ids = array_keys($data);
     //
     // Load fields from other storages
     //
     if ($ids && $this->post_fields) {
         // $fill[table][field] = null
         // needed for all rows to always contain all apropriate keys
         // in case when we're asked to load all fields from that table
         $fill = array_fill_keys(array_keys($this->post_fields), array());
         foreach (waContactFields::getAll('enabled') as $fid => $field) {
             /**
              * @var waContactField $field
              */
             $fill[$field->getStorage(true)][$fid] = false;
         }
         foreach ($this->post_fields as $table => $fields) {
             if ($table == '_internal') {
                 foreach ($fields as $f) {
                     /**
                      * @var $f string
                      */
                     if ($f == 'photo_url' || substr($f, 0, 10) == 'photo_url_') {
                         if ($f == 'photo_url') {
                             $size = null;
                         } else {
                             $size = substr($f, 10);
                         }
                         $retina = isset($this->options['photo_url_2x']) ? $this->options['photo_url_2x'] : null;
                         foreach ($data as $id => &$v) {
                             $v[$f] = waContact::getPhotoUrl($id, $v['photo'], $size, $size, $v['is_company'] ? 'company' : 'person', $retina);
                         }
                         unset($v);
                     } else {
                         switch ($f) {
                             case '_online_status':
                                 $llm = new waLoginLogModel();
                                 $contact_ids_map = $llm->select('DISTINCT contact_id')->where('datetime_out IS NULL')->fetchAll('contact_id');
                                 $timeout = waUser::getOption('online_timeout');
                                 foreach ($data as &$v) {
                                     if (isset($v['last_datetime']) && $v['last_datetime'] && $v['last_datetime'] != '0000-00-00 00:00:00') {
                                         if (time() - strtotime($v['last_datetime']) < $timeout) {
                                             if (isset($contact_ids_map[$v['id']])) {
                                                 $v['_online_status'] = 'online';
                                             } else {
                                                 $v['_online_status'] = 'offline';
                                             }
                                         }
                                     }
                                     $v['_online_status'] = 'offline';
                                 }
                                 unset($v);
                                 break;
                             case '_access':
                                 $rm = new waContactRightsModel();
                                 $accessStatus = $rm->getAccessStatus($ids);
                                 foreach ($data as $id => &$v) {
                                     if (!isset($accessStatus[$id])) {
                                         $v['_access'] = '';
                                         continue;
                                     }
                                     $v['_access'] = $accessStatus[$id];
                                 }
                                 unset($v);
                                 break;
                             default:
                                 throw new waException('Unknown internal field: ' . $f);
                         }
                     }
                 }
                 continue;
             }
             $data_fields = $fields;
             foreach ($data_fields as $k => $field_id) {
                 $f = waContactFields::get($field_id);
                 if ($f && $f instanceof waContactCompositeField) {
                     unset($data_fields[$k]);
                     $data_fields = array_merge($data_fields, $f->getField());
                 }
             }
             $model = $this->getModel($table);
             $post_data = $model->getData($ids, $data_fields);
             foreach ($post_data as $contact_id => $contact_data) {
                 foreach ($contact_data as $field_id => $value) {
                     if (!($f = waContactFields::get($field_id))) {
                         continue;
                     }
                     if (!$f->isMulti()) {
                         $post_data[$contact_id][$field_id] = isset($value[0]['data']) ? $value[0]['data'] : (is_array($value[0]) ? $value[0]['value'] : $value[0]);
                     }
                 }
             }
             if ($fields) {
                 $fill[$table] = array_fill_keys($fields, '');
             } else {
                 if (!isset($fill[$table])) {
                     $fill[$table] = array();
                 }
             }
             foreach ($data as $contact_id => $v) {
                 if (isset($post_data[$contact_id])) {
                     $data[$contact_id] += $post_data[$contact_id];
                 }
                 $data[$contact_id] += $fill[$table];
             }
         }
     }
     return $data;
 }
 /**
  * Merge given contacts into master contact, save, send merge event, then delete slaves.
  *
  * !!! Probably should move it into something like contactsHelper
  *
  * @param array $merge_ids list of contact ids
  * @param int $master_id contact id to merge others into
  * @return array
  */
 public static function merge($merge_ids, $master_id)
 {
     $merge_ids[] = $master_id;
     // List of contacts to merge
     $collection = new contactsCollection('id/' . implode(',', $merge_ids));
     $contacts_data = $collection->getContacts('*');
     // Master contact data
     if (!$master_id || !isset($contacts_data[$master_id])) {
         throw new waException('No contact to merge into.');
     }
     $master_data = $contacts_data[$master_id];
     unset($contacts_data[$master_id]);
     $master = new waContact($master_id);
     $result = array('total_requested' => count($contacts_data) + 1, 'total_merged' => 0, 'error' => '', 'users' => 0);
     if ($master_data['photo']) {
         $filename = wa()->getDataPath(waContact::getPhotoDir($master_data['id']) . "{$master_data['photo']}.original.jpg", true, 'contacts');
         if (!file_exists($filename)) {
             $master_data['photo'] = null;
         }
     }
     $data_fields = waContactFields::getAll('enabled');
     $check_duplicates = array();
     // field_id => true
     $update_photo = null;
     // if need to update photo here it is file paths
     // merge loop
     foreach ($contacts_data as $id => $info) {
         if ($info['is_user'] > 0) {
             $result['users']++;
             unset($contacts_data[$id]);
             continue;
         }
         foreach ($data_fields as $f => $field) {
             if (!empty($info[$f])) {
                 if ($field->isMulti()) {
                     $master->add($f, $info[$f]);
                     $check_duplicates[$f] = true;
                 } else {
                     // Field does not allow multiple values.
                     // Set value if no value yet.
                     if (empty($master_data[$f])) {
                         $master[$f] = $master_data[$f] = $info[$f];
                     }
                 }
             }
         }
         // photo
         if (!$master_data['photo'] && $info['photo'] && !$update_photo) {
             $filename_original = wa()->getDataPath(waContact::getPhotoDir($info['id']) . "{$info['photo']}.original.jpg", true, 'contacts');
             if (file_exists($filename_original)) {
                 $update_photo = array('original' => $filename_original);
                 $filename_crop = wa()->getDataPath(waContact::getPhotoDir($info['id']) . "{$info['photo']}.jpg", true, 'contacts');
                 if (file_exists($filename_crop)) {
                     $update_photo['crop'] = $filename_crop;
                 }
             }
         }
         // birthday parts
         if (!empty($data_fields['birthday'])) {
             foreach (array('birth_day', 'birth_month', 'birth_year') as $f) {
                 if (empty($master_data[$f]) && !empty($info[$f])) {
                     $master[$f] = $master_data[$f] = $info[$f];
                 }
             }
         }
     }
     // Remove duplicates
     foreach (array_keys($check_duplicates) as $f) {
         $values = $master[$f];
         if (!is_array($values) || count($values) <= 1) {
             continue;
         }
         $unique_values = array();
         // md5 => true
         foreach ($values as $k => $v) {
             if (is_array($v)) {
                 if (isset($v['value']) && is_string($v['value'])) {
                     $v = $v['value'];
                 } else {
                     unset($v['ext'], $v['status']);
                     ksort($v);
                     $v = serialize($v);
                 }
             }
             $hash = md5(mb_strtolower($v));
             if (!empty($unique_values[$hash])) {
                 unset($values[$k]);
                 continue;
             }
             $unique_values[$hash] = true;
         }
         $master[$f] = array_values($values);
     }
     // Save master contact
     $errors = $master->save(array(), 42);
     // 42 == do not validate anything at all
     if ($errors) {
         $errormsg = array();
         foreach ($errors as $field => $err) {
             if (!is_array($err)) {
                 $err = array($err);
             }
             foreach ($err as $str) {
                 $errormsg[] = $field . ': ' . $str;
             }
         }
         $result['error'] = implode("\n<br>", $errormsg);
         return $result;
     }
     // Merge categories
     $category_ids = array();
     $ccm = new waContactCategoriesModel();
     foreach ($ccm->getContactsCategories($merge_ids) as $cid => $cats) {
         $category_ids += array_flip($cats);
     }
     $category_ids = array_keys($category_ids);
     $ccm->add($master_id, $category_ids);
     // update photo
     if ($update_photo) {
         $rand = mt_rand();
         $path = wa()->getDataPath(waContact::getPhotoDir($master['id']), true, 'contacts', false);
         // delete old image
         if (file_exists($path)) {
             waFiles::delete($path);
         }
         waFiles::create($path);
         $filename = $path . "/" . $rand . ".original.jpg";
         waFiles::create($filename);
         waImage::factory($update_photo['original'])->save($filename, 90);
         if (!empty($update_photo['crop'])) {
             $filename = $path . "/" . $rand . ".jpg";
             waFiles::create($filename);
             waImage::factory($update_photo['crop'])->save($filename, 90);
         } else {
             waFiles::copy($filename, $path . "/" . $rand . ".jpg");
         }
         $master->save(array('photo' => $rand));
     }
     $result['total_merged'] = count($contacts_data) + 1;
     $contact_ids = array_keys($contacts_data);
     // wa_log
     $log_model = new waLogModel();
     $log_model->updateByField('contact_id', $contact_ids, array('contact_id' => $master_id));
     // wa_login_log
     $login_log_model = new waLoginLogModel();
     $login_log_model->updateByField('contact_id', $contact_ids, array('contact_id' => $master_id));
     // Merge event
     $params = array('contacts' => $contact_ids, 'id' => $master_data['id']);
     wa()->event(array('contacts', 'merge'), $params);
     // Delete all merged contacts
     $contact_model = new waContactModel();
     $contact_model->delete($contact_ids, false);
     // false == do not trigger event
     $history_model = new contactsHistoryModel();
     foreach ($contact_ids as $contact_id) {
         $history_model->deleteByField(array('type' => 'add', 'hash' => '/contact/' . $contact_id));
     }
     return $result;
 }
Ejemplo n.º 5
0
 /**
  * Returns user's status: "online", "offline"
  *
  * @return string
  */
 public function getStatus()
 {
     $timeout = self::$options['online_timeout'];
     // in sec
     if (($last = $this->get('last_datetime')) && $last != '0000-00-00 00:00:00') {
         if (time() - strtotime($last) < $timeout) {
             $m = new waLoginLogModel();
             $datetime_out = $m->select('datetime_out')->where('contact_id = i:0', array($this->id))->order('id DESC')->limit(1)->fetchField();
             if ($datetime_out === null) {
                 return 'online';
             } else {
                 return 'offline';
             }
         }
     }
     return 'offline';
 }
Ejemplo n.º 6
0
 /**
  * Delete one or more contacts and fire event сontacts.delete
  *
  * @event contacts.delete
  *
  * @param int|array $id - contact id or array of contact ids
  * @return bool
  */
 public function delete($id, $send_event = true)
 {
     if ($send_event) {
         // Fire @event contacts.delete allowing other applications to clean up their data
         wa()->event(array('contacts', 'delete'), $id);
     }
     if (is_array($id)) {
         $nid = array();
         foreach ($id as $i) {
             $nid[] = -(int) $i;
         }
     } else {
         $nid = -(int) $id;
     }
     // Delete rights
     $right_model = new waContactRightsModel();
     $right_model->deleteByField('group_id', $nid);
     // Delete settings
     $setting_model = new waContactSettingsModel();
     $setting_model->deleteByField('contact_id', $id);
     // Delete emails
     $contact_email_model = new waContactEmailsModel();
     $contact_email_model->deleteByField('contact_id', $id);
     // Delete from groups
     $user_groups_model = new waUserGroupsModel();
     $user_groups_model->deleteByField('contact_id', $id);
     // Delete from contact lists
     if (class_exists('contactsContactListsModel')) {
         // @todo: Use plugin for contacts
         $contact_lists_model = new contactsContactListsModel();
         $contact_lists_model->deleteByField('contact_id', $id);
     }
     // Delete from contact rights
     $contact_rights_model = new contactsRightsModel();
     $contact_rights_model->deleteByField('group_id', $nid);
     // Delete data
     $contact_data_model = new waContactDataModel();
     $contact_data_model->deleteByField('contact_id', $id);
     $contact_data_text_model = new waContactDataTextModel();
     $contact_data_text_model->deleteByField('contact_id', $id);
     // Delete contact from logs
     $login_log_model = new waLoginLogModel();
     $login_log_model->deleteByField('contact_id', $id);
     // Delete contact
     return $this->deleteById($id);
 }