public function postExecute($order_id = null, $result = null)
 {
     $data = parent::postExecute($order_id, $result);
     $log_model = new waLogModel();
     $log_model->add('order_complete', $order_id);
     $order_model = new shopOrderModel();
     if (is_array($order_id)) {
         $order = $order_id;
         $order_id = $order['id'];
     } else {
         $order = $order_model->getById($order_id);
     }
     shopCustomers::recalculateTotalSpent($order['contact_id']);
     if ($order !== null) {
         $log_model = new shopOrderLogModel();
         $state_id = $log_model->getPreviousState($order_id);
         $app_settings_model = new waAppSettingsModel();
         $update_on_create = $app_settings_model->get('shop', 'update_stock_count_on_create_order');
         if (!$update_on_create && $state_id == 'new') {
             // jump through 'processing' state - reduce
             // for logging changes in stocks
             shopProductStocksLogModel::setContext(shopProductStocksLogModel::TYPE_ORDER, 'Order %s was completed', array('order_id' => $order_id));
             $order_model = new shopOrderModel();
             $order_model->reduceProductsFromStocks($order_id);
             shopProductStocksLogModel::clearContext();
         }
         $order_model->recalculateProductsTotalSales($order_id);
     }
     return $data;
 }
 public function postExecute($order_id = null, $result = null)
 {
     $data = parent::postExecute($order_id, $result);
     if ($order_id != null) {
         $log_model = new waLogModel();
         $log_model->add('order_delete', $order_id);
         $order_model = new shopOrderModel();
         $app_settings_model = new waAppSettingsModel();
         if ($data['before_state_id'] != 'refunded') {
             $update_on_create = $app_settings_model->get('shop', 'update_stock_count_on_create_order');
             // for logging changes in stocks
             shopProductStocksLogModel::setContext(shopProductStocksLogModel::TYPE_ORDER, 'Order %s was deleted', array('order_id' => $order_id));
             if ($update_on_create) {
                 $order_model->returnProductsToStocks($order_id);
             } else {
                 if (!$update_on_create && $data['before_state_id'] != 'new') {
                     $order_model->returnProductsToStocks($order_id);
                 }
             }
             shopProductStocksLogModel::clearContext();
         }
         $order = $order_model->getById($order_id);
         if ($order && $order['paid_date']) {
             // Remember paid_date in log params for Restore action
             $olpm = new shopOrderLogParamsModel();
             $olpm->insert(array('name' => 'paid_date', 'value' => $order['paid_date'], 'order_id' => $order_id, 'log_id' => $data['id']));
             // Empty paid_date and update stats so that deleted orders do not affect reports
             $order_model->updateById($order_id, array('paid_date' => null, 'paid_year' => null, 'paid_month' => null, 'paid_quarter' => null));
             $order_model->recalculateProductsTotalSales($order_id);
             shopCustomers::recalculateTotalSpent($order['contact_id']);
         }
     }
     return $data;
 }
 public function execute($params = null)
 {
     $result = array();
     // from payment callback
     if (is_array($params)) {
         $order_id = $params['order_id'];
         $result['text'] = $params['plugin'] . ' (' . $params['view_data'] . ' - ' . $params['amount'] . ' ' . $params['currency_id'] . ')';
         $result['update']['params'] = array('payment_transaction_id' => $params['id']);
     } else {
         $order_id = $params;
         $result['text'] = waRequest::post('text', '');
     }
     $order_model = new shopOrderModel();
     $order = $order_model->getById($order_id);
     $log_model = new waLogModel();
     if (wa()->getEnv() == 'backend') {
         $log_model->add('order_pay', $order_id);
     } else {
         $log_model->add('order_pay_callback', $order_id, $order['contact_id']);
     }
     if (!$order['paid_year']) {
         shopAffiliate::applyBonus($order_id);
         if (wa('shop')->getConfig()->getOption('order_paid_date') == 'create') {
             $time = strtotime($order['create_datetime']);
         } else {
             $time = time();
         }
         $result['update'] = array('paid_year' => date('Y', $time), 'paid_quarter' => floor((date('n', $time) - 1) / 3) + 1, 'paid_month' => date('n', $time), 'paid_date' => date('Y-m-d', $time));
         if (!$order_model->where("contact_id = ? AND paid_date IS NOT NULL", $order['contact_id'])->limit(1)->fetch()) {
             $result['update']['is_first'] = 1;
         }
     }
     return $result;
 }
 public function postExecute($order_id = null, $result = null)
 {
     $data = parent::postExecute($order_id, $result);
     if ($order_id != null) {
         $log_model = new waLogModel();
         $log_model->add('order_restore', $order_id);
         $order_model = new shopOrderModel();
         $app_settings_model = new waAppSettingsModel();
         if ($this->state_id != 'refunded') {
             // for logging changes in stocks
             shopProductStocksLogModel::setContext(shopProductStocksLogModel::TYPE_ORDER, 'Order %s was restored', array('order_id' => $order_id));
             $update_on_create = $app_settings_model->get('shop', 'update_stock_count_on_create_order');
             if ($update_on_create) {
                 $order_model->reduceProductsFromStocks($order_id);
             } else {
                 if (!$update_on_create && $this->state_id != 'new') {
                     $order_model->reduceProductsFromStocks($order_id);
                 }
             }
             shopProductStocksLogModel::clearContext();
         }
         $order = $order_model->getById($order_id);
         if ($order && $order['paid_date']) {
             shopAffiliate::applyBonus($order_id);
             shopCustomers::recalculateTotalSpent($order['contact_id']);
         }
     }
     return $data;
 }
Example #5
0
 /**
  * Add record to table wa_log
  *
  * @param string $action
  * @param mixed $params
  * @param int $subject_contact_id
  * @param int $contact_id - actor contact id
  * @throws waException
  * @return bool|int
  */
 public function logAction($action, $params = null, $subject_contact_id = null, $contact_id = null)
 {
     if (!class_exists('waLogModel')) {
         wa('webasyst');
     }
     $log_model = new waLogModel();
     return $log_model->add($action, $params, $subject_contact_id, $contact_id);
 }
 /**
  * @param waContact $user
  * @return string
  */
 public static function getAccessDisableMsg($user)
 {
     $access_disable = '';
     if ($user['is_user'] == '-1') {
         $log_model = new waLogModel();
         $log_item = $log_model->select('*')->where("subject_contact_id = i:id AND action = 'access_disable'", array('id' => $user['id']))->order('datetime DESC')->limit(1)->fetch();
         if ($log_item) {
             $contact = new waContact($log_item['contact_id']);
             $name = htmlspecialchars(waContactNameField::formatName($contact));
             $access_disable = _w("Access disabled by") . " <a href='#/contact/{$log_item['contact_id']}/'>{$name}</a>, " . wa_date("humandatetime", $log_item['datetime']);
         }
     }
     return $access_disable;
 }
 public function postExecute($order_id = null, $result = null)
 {
     $data = parent::postExecute($order_id, $result);
     if ($order_id != null) {
         $log_model = new waLogModel();
         $log_model->add('order_process', $order_id);
         $app_settings_model = new waAppSettingsModel();
         if (!$app_settings_model->get('shop', 'update_stock_count_on_create_order')) {
             // for logging changes in stocks
             shopProductStocksLogModel::setContext(shopProductStocksLogModel::TYPE_ORDER, 'Order %s was processed', array('order_id' => $order_id));
             $order_model = new shopOrderModel();
             $order_model->reduceProductsFromStocks($order_id);
             shopProductStocksLogModel::clearContext();
         }
     }
     return $data;
 }
 public function postExecute($order_id = null, $result = null)
 {
     $data = parent::postExecute($order_id, $result);
     $order_model = new shopOrderModel();
     if (is_array($order_id)) {
         $order = $order_id;
         $order_id = $order['id'];
     } else {
         $order = $order_model->getById($order_id);
     }
     shopCustomers::recalculateTotalSpent($order['contact_id']);
     if ($order_id != null) {
         $log_model = new waLogModel();
         $log_model->add('order_refund', $order_id);
         $order_model = new shopOrderModel();
         $order_model->updateById($order_id, array('paid_date' => null, 'paid_year' => null, 'paid_month' => null, 'paid_quarter' => null));
         // for logging changes in stocks
         shopProductStocksLogModel::setContext(shopProductStocksLogModel::TYPE_ORDER, 'Order %s was refunded', array('order_id' => $order_id));
         $order_model->returnProductsToStocks($order_id);
         shopAffiliate::cancelBonus($order_id);
         $order_model->recalculateProductsTotalSales($order_id);
     }
     return $data;
 }
 public function postExecute($params = null, $result = null)
 {
     if (is_array($params)) {
         $order_id = $params['order_id'];
     } else {
         $order_id = $params;
     }
     $data = parent::postExecute($order_id, $result);
     $log_model = new waLogModel();
     $log_model->add('order_ship', $order_id);
     $log_model = new shopOrderLogModel();
     $state_id = $log_model->getPreviousState($order_id);
     $app_settings_model = new waAppSettingsModel();
     $update_on_create = $app_settings_model->get('shop', 'update_stock_count_on_create_order');
     if (!$update_on_create && $state_id == 'new') {
         // for logging changes in stocks
         shopProductStocksLogModel::setContext(shopProductStocksLogModel::TYPE_ORDER, 'Order %s was shipped', array('order_id' => $order_id));
         // jump through 'processing' state - reduce
         $order_model = new shopOrderModel();
         $order_model->reduceProductsFromStocks($order_id);
         shopProductStocksLogModel::clearContext();
     }
     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;
 }
 public function execute($data = null)
 {
     $order_model = new shopOrderModel();
     $order = $order_model->getById($data['id']);
     $subtotal = 0;
     $services = $products = array();
     foreach ($data['items'] as $item) {
         if ($item['service_id']) {
             $services[] = $item['service_id'];
         } else {
             $products[] = $item['product_id'];
         }
     }
     $service_model = new shopServiceModel();
     $product_model = new shopProductModel();
     $services = $service_model->getById($services);
     $products = $product_model->getById($products);
     foreach ($data['items'] as &$item) {
         $item['currency'] = $order['currency'];
         $item['price'] = $this->price($item['price']);
         if ($item['service_id']) {
             $item['service'] = $services[$item['service_id']];
         } else {
             $item['product'] = $products[$item['product_id']];
         }
         $subtotal += $item['price'] * $item['quantity'];
     }
     unset($item);
     foreach (array('shipping', 'discount') as $k) {
         if (!isset($data[$k])) {
             $data[$k] = 0;
         }
     }
     $contact = new waContact($order['contact_id']);
     $shipping_address = $contact->getFirst('address.shipping');
     if (!$shipping_address) {
         $shipping_address = $contact->getFirst('address');
     }
     $shipping_address = $shipping_address ? $shipping_address['data'] : array();
     $billing_address = $contact->getFirst('address.billing');
     if (!$billing_address) {
         $billing_address = $contact->getFirst('address');
     }
     $billing_address = $billing_address ? $billing_address['data'] : array();
     $discount_rate = $subtotal ? $data['discount'] / $subtotal : 0;
     $taxes = shopTaxes::apply($data['items'], array('shipping' => $shipping_address, 'billing' => $billing_address, 'discount_rate' => $discount_rate), $order['currency']);
     $tax = $tax_included = 0;
     foreach ($taxes as $t) {
         if (isset($t['sum'])) {
             $tax += $t['sum'];
         }
         if (isset($t['sum_included'])) {
             $tax_included += $t['sum_included'];
         }
     }
     $data['tax'] = $tax_included + $tax;
     $data['total'] = $subtotal + $tax + $this->price($data['shipping']) - $this->price($data['discount']);
     // for logging changes in stocks
     shopProductStocksLogModel::setContext(shopProductStocksLogModel::TYPE_ORDER, 'Order %s was edited', array('order_id' => $data['id']));
     // update
     $order_model->update($data, $data['id']);
     $log_model = new waLogModel();
     $log_model->add('order_edit', $data['id']);
     shopProductStocksLogModel::clearContext();
     if (!empty($data['params'])) {
         $params_model = new shopOrderParamsModel();
         $params_model->set($data['id'], $data['params'], false);
     }
     return true;
 }
 public function execute($params = null)
 {
     $log_model = new waLogModel();
     $log_model->add('order_comment', $params);
     return array('text' => waRequest::post('text'));
 }
Example #13
0
 /**
  * Saves contact's data to database.
  *
  * @param array $data Associative array of contact property values.
  * @param bool $validate Flag requiring to validate property values. Defaults to false.
  * @return int|array Zero, if saved successfully, or array of error messages otherwise
  */
 public function save($data = array(), $validate = false)
 {
     $is_user = $this->get('is_user');
     $add = array();
     foreach ($data as $key => $value) {
         if (strpos($key, '.')) {
             $key_parts = explode('.', $key);
             $f = waContactFields::get($key_parts[0]);
             if ($f) {
                 $key = $key_parts[0];
                 if ($key_parts[1] && $f->isExt()) {
                     // add next field
                     $add[$key] = true;
                     if (is_array($value)) {
                         if (!isset($value['value'])) {
                             $value = array('ext' => $key_parts[1], 'value' => $value);
                         }
                     } else {
                         $value = array('ext' => $key_parts[1], 'value' => $value);
                     }
                 }
             }
         } else {
             $f = waContactFields::get($key);
         }
         if ($f) {
             $this->data[$key] = $f->set($this, $value, array(), isset($add[$key]) ? true : false);
         } else {
             if ($key == 'password') {
                 $value = self::getPasswordHash($value);
             }
             $this->data[$key] = $value;
         }
     }
     $this->data['name'] = $this->get('name');
     $this->data['firstname'] = $this->get('firstname');
     $this->data['is_company'] = $this->get('is_company');
     if ($this->id && isset($this->data['is_user'])) {
         $log_model = new waLogModel();
         if ($this->data['is_user'] == '-1' && $is_user != '-1') {
             $log_model->add('access_disable', null, $this->id, wa()->getUser()->getId());
         } else {
             if ($this->data['is_user'] != '-1' && $is_user == '-1') {
                 $log_model->add('access_enable', null, $this->id, wa()->getUser()->getId());
             }
         }
     }
     $save = array();
     $errors = array();
     $contact_model = new waContactModel();
     foreach ($this->data as $field => $value) {
         if ($field == 'login') {
             $f = new waContactStringField('login', _ws('Login'), array('unique' => true, 'storage' => 'info'));
         } else {
             $f = waContactFields::get($field, $this['is_company'] ? 'company' : 'person');
         }
         if ($f) {
             if ($f->isMulti() && !is_array($value)) {
                 $value = array($value);
             }
             if ($f->isMulti()) {
                 foreach ($value as &$val) {
                     if (is_string($val)) {
                         $val = trim($val);
                     } else {
                         if (isset($val['value']) && is_string($val['value'])) {
                             $val['value'] = trim($val['value']);
                         } else {
                             if ($f instanceof waContactCompositeField && isset($val['data']) && is_array($val['data'])) {
                                 foreach ($val['data'] as &$v) {
                                     if (is_string($v)) {
                                         $v = trim($v);
                                     }
                                 }
                                 unset($v);
                             }
                         }
                     }
                 }
                 unset($val);
             } else {
                 if (is_string($value)) {
                     $value = trim($value);
                 } else {
                     if (isset($value['value']) && is_string($value['value'])) {
                         $value['value'] = trim($value['value']);
                     } else {
                         if ($f instanceof waContactCompositeField && isset($value['data']) && is_array($value['data'])) {
                             foreach ($value['data'] as &$v) {
                                 if (is_string($v)) {
                                     $v = trim($v);
                                 }
                             }
                             unset($v);
                         }
                     }
                 }
             }
             if ($validate !== 42) {
                 // this deep dark magic is used when merging contacts
                 if ($validate) {
                     if ($e = $f->validate($value, $this->id)) {
                         $errors[$f->getId()] = $e;
                     }
                 } elseif ($f->isUnique()) {
                     // validate unique
                     if ($e = $f->validateUnique($value, $this->id)) {
                         $errors[$f->getId()] = $e;
                     }
                 }
             }
             if (!$errors && $f->getStorage()) {
                 $save[$f->getStorage()->getType()][$field] = $f->prepareSave($value, $this);
             }
         } elseif ($contact_model->fieldExists($field)) {
             $save['waContactInfoStorage'][$field] = $value;
         } else {
             $save['waContactDataStorage'][$field] = $value;
         }
     }
     // Returns errors
     if ($errors) {
         return $errors;
     }
     $is_add = false;
     // Saving to all storages
     try {
         if (!$this->id) {
             $is_add = true;
             $storage = 'waContactInfoStorage';
             if (wa()->getEnv() == 'frontend') {
                 if ($ref = waRequest::cookie('referer')) {
                     $save['waContactDataStorage']['referer'] = $ref;
                     $save['waContactDataStorage']['referer_host'] = parse_url($ref, PHP_URL_HOST);
                 }
                 if ($utm = waRequest::cookie('utm')) {
                     $utm = json_decode($utm, true);
                     if ($utm && is_array($utm)) {
                         foreach ($utm as $k => $v) {
                             $save['waContactDataStorage']['utm_' . $k] = $v;
                         }
                     }
                 }
             }
             $this->id = waContactFields::getStorage($storage)->set($this, $save[$storage]);
             unset($save[$storage]);
         }
         foreach ($save as $storage => $storage_data) {
             waContactFields::getStorage($storage)->set($this, $storage_data);
         }
         $this->data = array();
         wa()->event(array('contacts', 'save'), $this);
         $this->removeCache();
         $this->clearDisabledFields();
     } catch (Exception $e) {
         // remove created contact
         if ($is_add && $this->id) {
             $this->delete();
             $this->id = null;
         }
         $errors['name'][] = $e->getMessage();
     }
     return $errors ? $errors : 0;
 }
 public function getLogs($filters = array(), &$count = null)
 {
     $log_model = new waLogModel();
     $apps = wa()->getUser()->getApps();
     if (!isset($filters['app_id']) || !is_array($filters['app_id'])) {
         $user_filter = wa()->getUser()->getSettings('webasyst', 'dashboard_activity');
         if ($user_filter) {
             $filters['app_id'] = explode(',', $user_filter);
         }
     }
     if (!$this->getUser()->isAdmin()) {
         if (!empty($filters['app_id'])) {
             $filters['app_id'] = array_keys(array_intersect_key(array_flip($filters['app_id']), $apps));
         } else {
             $filters['app_id'] = array_keys($apps);
         }
     }
     $rows = $log_model->getLogs($filters);
     $count = count($rows);
     $apps = wa()->getApps(true);
     $apps_rows = array();
     $prev = array();
     foreach ($rows as $row_id => &$row) {
         if ($prev) {
             $flag = true;
             foreach (array('app_id', 'action', 'contact_id', 'subject_contact_id', 'params') as $k) {
                 if ($prev[$k] != $row[$k]) {
                     $flag = false;
                     break;
                 }
             }
             if ($flag) {
                 unset($rows[$row_id]);
                 continue;
             }
         }
         $contact_name = waContactNameField::formatName($row);
         if ($contact_name) {
             $row['contact_name'] = $contact_name;
         }
         if ($row['is_user']) {
             $row['contact_photo_url'] = waContact::getPhotoUrl($row['contact_id'], $row['contact_photo'], 32, 32);
         }
         $row['datetime_group'] = $this->getDatetimeGroup($row['datetime']);
         if (!empty($apps[$row['app_id']])) {
             $row['app'] = $apps[$row['app_id']];
             $logs = wa($row['app_id'])->getConfig()->getLogActions(true);
             $row['action_name'] = ifset($logs[$row['action']]['name'], $row['action']);
             if (strpos($row['action'], 'del')) {
                 $row['type'] = 4;
             } elseif (strpos($row['action'], 'add')) {
                 $row['type'] = 3;
             } else {
                 $row['type'] = 1;
             }
             $apps_rows[$row['app_id']][$row_id] = $row;
         } else {
             $row['app'] = array('name' => $row['app_id']);
             $row['action_name'] = $row['action'];
             $row['type'] = 1;
         }
         $prev = $row;
         unset($row);
     }
     foreach ($apps_rows as $app_id => $app_rows) {
         $app_rows = wa($app_id)->getConfig()->explainLogs($app_rows);
         foreach ($app_rows as $row_id => $row) {
             if ($row) {
                 $rows[$row_id] = $row;
             } else {
                 unset($rows[$row_id]);
             }
         }
     }
     return $rows;
 }
 public function uninstall()
 {
     // check uninstall.php
     $file = $this->getAppConfigPath('uninstall');
     if (file_exists($file)) {
         include $file;
     }
     $file_db = $this->getAppPath('lib/config/db.php');
     if (file_exists($file_db)) {
         $schema = (include $file_db);
         $model = new waModel();
         foreach ($schema as $table => $fields) {
             $sql = "DROP TABLE IF EXISTS " . $table;
             $model->exec($sql);
         }
     }
     // Remove all app settings
     $app_settings_model = new waAppSettingsModel();
     $app_settings_model->del($this->application);
     $contact_settings_model = new waContactSettingsModel();
     $contact_settings_model->deleteByField('app_id', $this->application);
     // Remove all rights to app
     $contact_rights_model = new waContactRightsModel();
     $contact_rights_model->deleteByField('app_id', $this->application);
     // Remove logs
     $log_model = new waLogModel();
     $log_model->deleteByField('app_id', $this->application);
     // Remove cache
     waFiles::delete($this->getPath('cache') . '/apps/' . $this->application);
 }
 public function dispatch()
 {
     try {
         if (preg_match('/^sitemap-?([a-z0-9_]+)?(-([0-9]+))?.xml$/i', $this->config->getRequestUrl(true), $m)) {
             $app_id = isset($m[1]) ? $m[1] : 'webasyst';
             if ($this->appExists($app_id)) {
                 self::getInstance($app_id);
                 $class = $app_id . 'SitemapConfig';
                 if (class_exists($class)) {
                     /**
                      * @var $sitemap waSitemapConfig
                      */
                     $sitemap = new $class();
                     $n = ifempty($m[3]);
                     if (!$n) {
                         $n = 1;
                     }
                     $sitemap->display($n);
                 }
             } else {
                 throw new waException("Page not found", 404);
             }
         } elseif (preg_match('/^([a-z0-9_]+)?\\/?captcha\\.php$/i', $this->config->getRequestUrl(true, true), $m)) {
             $app_id = isset($m[1]) ? $m[1] : 'webasyst';
             if ($this->appExists($app_id)) {
                 $wa = self::getInstance($app_id, null, true);
                 $captcha = $wa->getCaptcha(array('app_id' => $app_id));
                 $captcha->display();
             } else {
                 throw new waException("Page not found", 404);
             }
         } elseif (!strncmp($this->config->getRequestUrl(true), 'oauth.php', 9)) {
             $app_id = $this->getStorage()->get('auth_app', 'webasyst');
             $app_system = self::getInstance($app_id);
             if (class_exists($app_id . 'OAuthController')) {
                 $app_system->getFrontController()->execute(null, 'OAuth');
             } else {
                 wa('webasyst')->getFrontController()->execute(null, 'OAuth');
             }
         } elseif (!strncmp($this->config->getRequestUrl(true), 'payments.php/', 13)) {
             $url = substr($this->config->getRequestUrl(true), 13);
             waRequest::setParam('module_id', strtok($url, '/?'));
             $webasyst_system = self::getInstance('webasyst');
             $webasyst_system->getFrontController()->execute(null, 'payments', null, true);
         } elseif ($this->getEnv() == 'backend' && !$this->getUser()->isAuth()) {
             $webasyst_system = self::getInstance('webasyst', null, true);
             $webasyst_system->getFrontController()->execute(null, 'login', waRequest::get('action'), true);
         } elseif ($this->config instanceof waAppConfig) {
             if ($this->getEnv() == 'backend' && !$this->getUser()->getRights($this->getConfig()->getApplication(), 'backend')) {
                 header("Location: " . $this->getConfig()->getBackendUrl(true));
                 exit;
             }
             $this->getFrontController()->dispatch();
         } else {
             $app = null;
             $route = null;
             if ($this->getEnv() == 'frontend') {
                 // logout
                 if (null !== ($logout_url = waRequest::get('logout'))) {
                     // for getting app
                     $this->getRouting()->dispatch();
                     $app = waRequest::param('app');
                     // For logging logout action
                     $data = array('app_id' => $app, 'contact_id' => $this->getUser()->getId(), 'datetime' => date("Y-m-d H:i:s"), 'action' => 'logout', 'params' => $this->getEnv());
                     // logout itself
                     $this->getAuth()->clearAuth();
                     if (!$logout_url) {
                         $logout_url = $this->config->getRequestUrl(false, true);
                     }
                     // logging logout
                     if (!class_exists('waLogModel')) {
                         wa('webasyst');
                     }
                     $log_model = new waLogModel();
                     $log_model->insert($data);
                     // make redirect after logout
                     $this->getResponse()->redirect($logout_url);
                 }
                 if (!$this->getRouting()->dispatch()) {
                     $this->getResponse()->redirect($this->getConfig()->getBackendUrl(true), 302);
                 }
                 $app = waRequest::param('app');
             } else {
                 self::getInstance('webasyst');
                 $path = $this->getConfig()->getRequestUrl(true);
                 if (($i = strpos($path, '?')) !== false) {
                     $path = substr($path, 0, $i);
                 }
                 $url = explode("/", $path);
                 $app = isset($url[1]) && $url[1] != 'index.php' ? $url[1] : 'webasyst';
             }
             if (!$app) {
                 $app = 'webasyst';
             }
             $app_system = self::getInstance($app, null, true);
             if ($app != 'webasyst' && $this->getEnv() == 'backend' && !$this->getUser()->getRights($app_system->getConfig()->getApplication(), 'backend')) {
                 //$this->getResponse()->redirect($this->getConfig()->getBackendUrl(true), 302);
                 throw new waRightsException('Access to this app denied', 403);
             }
             if ((waRequest::param('secure') || waRequest::param('auth')) && !$this->getUser()->isAuth()) {
                 $auth = $this->getAuthConfig();
                 if (!empty($auth['app'])) {
                     $app_system = self::getInstance($auth['app'], null, true);
                 }
                 $app_system->login();
             } else {
                 $app_system->getFrontController()->dispatch();
             }
         }
     } catch (waApiException $e) {
         print $e;
     } catch (waException $e) {
         print $e;
     } catch (Exception $e) {
         if (waSystemConfig::isDebug()) {
             print $e;
         } else {
             $e = new waException($e->getMessage(), $e->getCode());
             print $e;
         }
     }
 }
 public function execute($data = null)
 {
     if (wa()->getEnv() == 'frontend') {
         // Now we are in frontend, so fill stock_id for items. Stock_id get from storefront-settings
         // But:
         //   - some skus may have not any stock
         //   - stock_id from storefront isn't setted (empty)
         $sku_ids = array();
         foreach ($data['items'] as $item) {
             if ($item['type'] == 'product') {
                 $sku_ids[] = (int) $item['sku_id'];
             }
         }
         $product_stocks_model = new shopProductStocksModel();
         $sku_ids = $product_stocks_model->filterSkusByNoStocks($sku_ids);
         $sku_ids_map = array_fill_keys($sku_ids, true);
         // storefront stock-id
         $stock_id = waRequest::param('stock_id');
         $stock_model = new shopStockModel();
         if (!$stock_id || !$stock_model->stockExists($stock_id)) {
             $stock_id = $stock_model->select('id')->order('sort')->limit(1)->fetchField();
         }
         foreach ($data['items'] as &$item) {
             if ($item['type'] == 'product') {
                 if (!isset($sku_ids_map[$item['sku_id']])) {
                     // have stocks
                     $item['stock_id'] = $stock_id;
                 }
             }
         }
     }
     $currency = wa()->getConfig()->getCurrency(false);
     $rate_model = new shopCurrencyModel();
     $row = $rate_model->getById($currency);
     $rate = $row['rate'];
     // Save contact
     if (isset($data['contact'])) {
         if (is_numeric($data['contact'])) {
             $contact = new waContact($data['contact']);
         } else {
             /**
              * @var waContact $contact
              */
             $contact = $data['contact'];
             if (!$contact->getId()) {
                 $contact->save();
                 // if user has been created
                 if ($contact['password']) {
                     $signup_action = new shopSignupAction();
                     $signup_action->send($contact);
                 }
             }
         }
     } else {
         $data['contact'] = $contact = wa()->getUser();
     }
     $subtotal = 0;
     foreach ($data['items'] as &$item) {
         if ($currency != $item['currency']) {
             $item['price'] = shop_currency($item['price'], $item['currency'], null, false);
             if (!empty($item['purchase_price'])) {
                 $item['purchase_price'] = shop_currency($item['purchase_price'], $item['currency'], null, false);
             }
             $item['currency'] = $currency;
         }
         $subtotal += $item['price'] * $item['quantity'];
     }
     unset($item);
     if ($data['discount'] === '') {
         $data['total'] = $subtotal;
         $data['discount'] = shopDiscounts::apply($data);
     }
     $shipping_address = $contact->getFirst('address.shipping');
     if (!$shipping_address) {
         $shipping_address = $contact->getFirst('address');
     }
     $billing_address = $contact->getFirst('address.billing');
     if (!$billing_address) {
         $billing_address = $contact->getFirst('address');
     }
     $discount_rate = $subtotal ? $data['discount'] / $subtotal : 0;
     $taxes = shopTaxes::apply($data['items'], array('shipping' => isset($shipping_address['data']) ? $shipping_address['data'] : array(), 'billing' => isset($billing_address['data']) ? $billing_address['data'] : array(), 'discount_rate' => $discount_rate));
     $tax = $tax_included = 0;
     foreach ($taxes as $t) {
         if (isset($t['sum'])) {
             $tax += $t['sum'];
         }
         if (isset($t['sum_included'])) {
             $tax_included += $t['sum_included'];
         }
     }
     $order = array('state_id' => 'new', 'total' => $subtotal - $data['discount'] + $data['shipping'] + $tax, 'currency' => $currency, 'rate' => $rate, 'tax' => $tax_included + $tax, 'discount' => $data['discount'], 'shipping' => $data['shipping'], 'comment' => isset($data['comment']) ? $data['comment'] : '');
     $order['contact_id'] = $contact->getId();
     // Add contact to 'shop' category
     $contact->addToCategory('shop');
     // Save order
     $order_model = new shopOrderModel();
     $order_id = $order_model->insert($order);
     // Create record in shop_customer, or update existing record
     $scm = new shopCustomerModel();
     $scm->updateFromNewOrder($order['contact_id'], $order_id);
     // save items
     $items_model = new shopOrderItemsModel();
     $parent_id = null;
     foreach ($data['items'] as $item) {
         $item['order_id'] = $order_id;
         if ($item['type'] == 'product') {
             $parent_id = $items_model->insert($item);
         } elseif ($item['type'] == 'service') {
             $item['parent_id'] = $parent_id;
             $items_model->insert($item);
         }
     }
     // Order params
     if (empty($data['params'])) {
         $data['params'] = array();
     }
     $data['params']['auth_code'] = self::generateAuthCode($order_id);
     $data['params']['auth_pin'] = self::generateAuthPin();
     // Save params
     $params_model = new shopOrderParamsModel();
     $params_model->set($order_id, $data['params']);
     $log_model = new waLogModel();
     $log_model->add('order_create', $order_id, null, $order['contact_id']);
     return array('order_id' => $order_id, 'contact_id' => wa()->getEnv() == 'frontend' ? $contact->getId() : wa()->getUser()->getId());
 }