├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── phpunit.xml ├── src ├── Amoapi.php ├── Api │ ├── Logger.php │ ├── Oauth │ │ └── Query.php │ ├── Query.php │ └── Response.php ├── ApiClient.php ├── Base │ ├── Collections │ │ ├── ApiModelCollection.php │ │ └── Collection.php │ ├── Methods │ │ ├── Get.php │ │ ├── LimitedList.php │ │ ├── Method.php │ │ └── Post.php │ ├── Models │ │ ├── ApiModel.php │ │ ├── CustomField │ │ │ ├── BirthDayField.php │ │ │ ├── CalendarField.php │ │ │ ├── CategoryField.php │ │ │ ├── ChainedList.php │ │ │ ├── CheckboxField.php │ │ │ ├── DateField.php │ │ │ ├── EmailField.php │ │ │ ├── EntityField.php │ │ │ ├── FileField.php │ │ │ ├── ImField.php │ │ │ ├── ItemsField.php │ │ │ ├── JurField.php │ │ │ ├── MultiSelectField.php │ │ │ ├── MultiTextField.php │ │ │ ├── NumericField.php │ │ │ ├── OrgField.php │ │ │ ├── PhoneField.php │ │ │ ├── RadioButtonField.php │ │ │ ├── SelectField.php │ │ │ ├── SmartAddressField.php │ │ │ ├── StreetAddressField.php │ │ │ ├── TextField.php │ │ │ ├── TextareaField.php │ │ │ └── UrlField.php │ │ ├── MainEntity.php │ │ ├── Model.php │ │ ├── ModelWithCF.php │ │ ├── Oauth │ │ │ └── QueryModel.php │ │ ├── QueryModel.php │ │ └── Traits │ │ │ ├── CatalogElements.php │ │ │ ├── EntityDetector.php │ │ │ ├── LinkedCatalogElements.php │ │ │ ├── LinkedCompany.php │ │ │ ├── LinkedContacts.php │ │ │ ├── LinkedCustomers.php │ │ │ ├── LinkedLeads.php │ │ │ ├── LinkedNotes.php │ │ │ ├── LinkedParents.php │ │ │ ├── LinkedPipeline.php │ │ │ ├── LinkedTags.php │ │ │ ├── LinkedTasks.php │ │ │ ├── LinkedTransactions.php │ │ │ ├── LinkedUsers.php │ │ │ └── MainContact.php │ ├── Services │ │ ├── Cached.php │ │ ├── LimitedList.php │ │ ├── MainEntity.php │ │ ├── Service.php │ │ └── Traits │ │ │ ├── SearchByCustomField.php │ │ │ ├── SearchByEmail.php │ │ │ ├── SearchByName.php │ │ │ └── SearchByPhone.php │ └── Storage │ │ ├── Oauth │ │ ├── AbstractStorage.php │ │ ├── FileStorage.php │ │ ├── LongTokenStorage.php │ │ ├── MongoDbStorage.php │ │ └── RedisStorage.php │ │ └── Query │ │ ├── AbstractStorage.php │ │ ├── FileStorage.php │ │ └── RedisStorage.php ├── Cache │ ├── .gitignore │ └── .htaccess ├── Collections │ ├── CatalogCollection.php │ ├── CatalogCustomFieldCollection.php │ ├── CatalogElementCollection.php │ ├── CollectionWrapper.php │ ├── CompaniesCustomFieldCollection.php │ ├── CompanyCollection.php │ ├── ContactCollection.php │ ├── ContactsCustomFieldCollection.php │ ├── CustomFieldCollection.php │ ├── CustomerCollection.php │ ├── CustomersCustomFieldCollection.php │ ├── EntityCustomFieldCollection.php │ ├── LeadCollection.php │ ├── LeadsCustomFieldCollection.php │ ├── NoteCollection.php │ ├── NoteTypesCollection.php │ ├── PipelineCollection.php │ ├── PipelineStatusesCollection.php │ ├── QueryCollection.php │ ├── ServiceCollection.php │ ├── TaskCollection.php │ ├── TaskTypesCollection.php │ ├── TransactionsCollection.php │ ├── UserCollection.php │ ├── UserGroupCollection.php │ └── WebhookCollection.php ├── Cookies │ ├── .gitignore │ └── .htaccess ├── Logs │ ├── .gitignore │ └── .htaccess ├── Methods │ ├── Account │ │ └── AccountCurrent.php │ ├── CatalogElements │ │ ├── CatalogElementsAdd.php │ │ ├── CatalogElementsDelete.php │ │ ├── CatalogElementsList.php │ │ └── CatalogElementsUpdate.php │ ├── Catalogs │ │ ├── CatalogsAdd.php │ │ ├── CatalogsDelete.php │ │ ├── CatalogsList.php │ │ └── CatalogsUpdate.php │ ├── Companies │ │ ├── CompaniesAdd.php │ │ ├── CompaniesList.php │ │ └── CompaniesUpdate.php │ ├── Contacts │ │ ├── ContactsAdd.php │ │ ├── ContactsList.php │ │ └── ContactsUpdate.php │ ├── Customers │ │ ├── CustomersAdd.php │ │ ├── CustomersDelete.php │ │ ├── CustomersList.php │ │ └── CustomersUpdate.php │ ├── Leads │ │ ├── LeadsAdd.php │ │ ├── LeadsList.php │ │ └── LeadsUpdate.php │ ├── Notes │ │ ├── NotesAdd.php │ │ ├── NotesList.php │ │ └── NotesUpdate.php │ ├── Tasks │ │ ├── TasksAdd.php │ │ ├── TasksList.php │ │ └── TasksUpdate.php │ ├── Transactions │ │ ├── TransactionsAdd.php │ │ ├── TransactionsDelete.php │ │ ├── TransactionsList.php │ │ └── TransactionsUpdate.php │ └── Webhooks │ │ ├── WebhooksList.php │ │ └── WebhooksSubscriber.php ├── Models │ ├── Account.php │ ├── AccountCustomFields.php │ ├── Catalog.php │ ├── CatalogElement.php │ ├── Company.php │ ├── Contact.php │ ├── CustomField.php │ ├── Customer.php │ ├── EntityCustomFields.php │ ├── Lead.php │ ├── Note.php │ ├── Pipeline.php │ ├── PipelineStatus.php │ ├── Task.php │ ├── Transaction.php │ ├── User.php │ ├── UserGroup.php │ └── Webhook.php ├── Oauthapi.php └── Services │ ├── Account.php │ ├── Ajax.php │ ├── CatalogElements.php │ ├── Catalogs.php │ ├── Companies.php │ ├── Contacts.php │ ├── Customers.php │ ├── Leads.php │ ├── Notes.php │ ├── Salesbots.php │ ├── Tasks.php │ ├── Transactions.php │ └── Webhooks.php └── tests ├── Cases ├── AjaxTest.php ├── AmoapiTest.php ├── CatalogsTest.php ├── CompaniesTest.php ├── ContactsTest.php ├── CustomersTest.php ├── LeadsTest.php ├── LinkedNotesTest.php └── LinkedTasksTest.php ├── Config.php └── TestCase.php /.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 ufee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ufee/amoapi", 3 | "homepage": "https://github.com/ufee", 4 | "description": "amoCRM API Client (https://www.amocrm.ru/developers/content/platform/abilities/)", 5 | "type": "library", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Vlad Ionov", 10 | "email": "vlad@ufee.ru", 11 | "role": "Creator" 12 | } 13 | ], 14 | "support": { 15 | "email": "vlad@ufee.ru", 16 | "issues": "https://github.com/ufee" 17 | }, 18 | "require": { 19 | "php": ">=5.6" 20 | }, 21 | "require-dev": { 22 | "phpunit/phpunit": "^5" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "Ufee\\Amo\\": "src/" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | ./tests/Cases 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/Api/Logger.php: -------------------------------------------------------------------------------- 1 | '', 13 | 'chunk' => 'm-Y', 14 | 'date_format' => "d.m.Y H:i:s \r\n-------------------\r\n", 15 | ]; 16 | protected static 17 | $_instances = []; 18 | 19 | 20 | /** 21 | * Constructor 22 | */ 23 | protected function __construct($name) 24 | { 25 | if (!is_string($name) && !is_array($name)) { 26 | throw new \Exception('Logger filename must be string or array'); 27 | } 28 | if (is_string($name)) { 29 | $name = ['name' => $name]; 30 | } 31 | $this->options = array_merge($this->options, $name); 32 | $this->options['name'] = ltrim($this->options['name'], '/'); 33 | } 34 | 35 | /** 36 | * Set default log path 37 | * @return Logger 38 | */ 39 | public function setDefaultPath() 40 | { 41 | if (strpos($this->options['name'], '/') > 0) { 42 | $exps = explode('/', $this->options['name']); 43 | $this->options['name'] = array_pop($exps); 44 | $this->path = $this->path.join('/', $exps).'/'; 45 | } 46 | if ($this->options['chunk'] != '') { 47 | $this->path .= date($this->options['chunk'].'/', time()); 48 | } 49 | $this->path = AMOAPI_ROOT.$this->path; 50 | if (!file_exists($this->path)) { 51 | mkdir($this->path); 52 | } 53 | } 54 | 55 | /** 56 | * Set custom log path 57 | * @return Logger 58 | */ 59 | public function setCustomPath($value) 60 | { 61 | $this->path = $value; 62 | if (!file_exists($this->path)) { 63 | mkdir($this->path); 64 | } 65 | return $this; 66 | } 67 | 68 | /** 69 | * Get instance 70 | * @return Logger 71 | */ 72 | public static function getInstance($name = null) 73 | { 74 | if (is_null($name)) { 75 | if (empty(static::$_instances)) { 76 | throw new \Exception('Empty logger instance'); 77 | } 78 | return end(static::$_instances); 79 | } 80 | if (!array_key_exists($name, static::$_instances)) { 81 | static::$_instances[$name] = new static($name); 82 | } 83 | return static::$_instances[$name]; 84 | } 85 | 86 | /** 87 | * Log data 88 | * @param mixed ... args 89 | * @return bool 90 | */ 91 | public function log() 92 | { 93 | $write = []; 94 | $args = func_get_args(); 95 | 96 | foreach ($args as $arg) { 97 | $data = trim(print_r($arg, 1)); 98 | if ($data !== '') { 99 | $write[]= $data; 100 | } 101 | } 102 | return file_put_contents( 103 | $this->path.'/'.$this->options['name'], 104 | date($this->options['date_format'], time())." - \t".join(" \r\n - \t", $write)."\r\n \r\n", 105 | FILE_APPEND | LOCK_EX 106 | ); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/Api/Query.php: -------------------------------------------------------------------------------- 1 | attributes['retries']++; 17 | $instance = $this->instance(); 18 | $last_time = 1; 19 | if ($last_query = $instance->queries->last()) { 20 | $last_time = $last_query->start_time; 21 | } 22 | $current_time = microtime(true); 23 | $time_offset = $current_time-$last_time; 24 | $delay = $instance->queries->getDelay(); 25 | if ($delay > $time_offset) { 26 | $sleep_time = (int)($delay-$time_offset)*1000000; 27 | usleep($sleep_time); 28 | $this->attributes['sleep_time'] = $sleep_time/1000000; 29 | } 30 | $this->attributes['start_time'] = microtime(true); 31 | $method = strtolower($this->method); 32 | $this->attributes['response'] = new Response( 33 | $this->$method(), $this 34 | ); 35 | curl_close($this->curl); 36 | $this->attributes['curl'] = null; 37 | $code = $this->response->getCode(); 38 | $instance->queries->pushByCode($code, $this); 39 | 40 | if (!in_array($code, [200, 204]) && file_exists($instance->queries->getCookiePath())) { 41 | @unlink($instance->queries->getCookiePath()); 42 | } 43 | if ($code == 401 && $this->url != $instance::AUTH_URL && $this->retries <= 3 && $instance->hasAutoAuth()) { 44 | $instance->authorize(); 45 | $instance->queries->refreshSession(); 46 | $this->setCurl(); 47 | return $this->execute(); 48 | } 49 | if ($code == 429 && $this->retries <= 24) { 50 | sleep(1); 51 | return $this->setCurl()->execute(); 52 | } 53 | if (in_array($code, [502,504]) && $this->retry) { 54 | sleep(1); 55 | $this->setCurl(); 56 | $this->setRetry(false); 57 | return $this->execute(); 58 | } 59 | $this->attributes['end_time'] = microtime(true); 60 | $this->attributes['execution_time'] = round($this->end_time - $this->start_time, 5); 61 | $this->attributes['memory_usage'] = memory_get_peak_usage(true)/1024/1024; 62 | $this->generateHash(); 63 | $instance->queries->pushQuery($this, in_array($code, [200])); 64 | 65 | if (!$instance->hasSession() && in_array($code, [200, 204])) { 66 | $instance->queries->refreshSession(); 67 | } 68 | return $this; 69 | } 70 | 71 | /** 72 | * GET query 73 | * @return Query 74 | */ 75 | private function get() 76 | { 77 | curl_setopt($this->curl, CURLOPT_URL, $this->getUrl()); 78 | curl_setopt($this->curl, CURLOPT_HTTPHEADER, $this->getHeaders()); 79 | 80 | return curl_exec($this->curl); 81 | } 82 | 83 | /** 84 | * POST query 85 | * @return Query 86 | */ 87 | private function post() 88 | { 89 | curl_setopt($this->curl, CURLOPT_URL, $this->getUrl()); 90 | curl_setopt($this->curl, CURLOPT_HTTPHEADER, $this->getHeaders()); 91 | curl_setopt($this->curl, CURLOPT_POST, true); 92 | 93 | if (!empty($this->attributes['json_data'])) { 94 | curl_setopt($this->curl, CURLOPT_POSTFIELDS, json_encode($this->json_data)); 95 | } else { 96 | curl_setopt($this->curl, CURLOPT_POSTFIELDS, http_build_query($this->post_data)); 97 | } 98 | return curl_exec($this->curl); 99 | } 100 | 101 | /** 102 | * PATCH query 103 | * @return Query 104 | */ 105 | private function patch() 106 | { 107 | curl_setopt($this->curl, CURLOPT_URL, $this->getUrl()); 108 | curl_setopt($this->curl, CURLOPT_HTTPHEADER, $this->getHeaders()); 109 | curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'PATCH'); 110 | curl_setopt($this->curl, CURLOPT_POSTFIELDS, json_encode($this->json_data)); 111 | 112 | return curl_exec($this->curl); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/Api/Response.php: -------------------------------------------------------------------------------- 1 | query = $query; 25 | $this->data = $data; 26 | $this->info = (object)curl_getinfo($query->curl); 27 | $this->code = $this->info->http_code; 28 | 29 | if ($this->code === 0) { 30 | $this->error = curl_error($query->curl); 31 | } 32 | } 33 | 34 | /** 35 | * Get response content 36 | * @return string 37 | */ 38 | public function getData() 39 | { 40 | return $this->data; 41 | } 42 | 43 | /** 44 | * Get json decoded content 45 | * @param bool $arr 46 | * @return mixed|null 47 | */ 48 | public function parseJson($arr = false) 49 | { 50 | return json_decode($this->data, $arr); 51 | } 52 | 53 | /** 54 | * Get response code 55 | * @return integer 56 | */ 57 | public function getCode() 58 | { 59 | return $this->code; 60 | } 61 | 62 | /** 63 | * Get response info 64 | * @return object 65 | */ 66 | public function getInfo() 67 | { 68 | return $this->info; 69 | } 70 | 71 | /** 72 | * Get response error 73 | * @return string|null 74 | */ 75 | public function getError() 76 | { 77 | return $this->error; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/Base/Collections/ApiModelCollection.php: -------------------------------------------------------------------------------- 1 | service = $service; 21 | } 22 | 23 | public function service() 24 | { 25 | return $this->service; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Base/Methods/Get.php: -------------------------------------------------------------------------------- 1 | $v) { 23 | $this->args[$k] = $v; 24 | } 25 | } else { 26 | $this->args[$key] = $value; 27 | } 28 | return $this; 29 | } 30 | 31 | /** 32 | * Call api method 33 | * @param array $arg 34 | * @return Collection 35 | */ 36 | public function call($arg = []) 37 | { 38 | if ($this->service->instance instanceOf \Ufee\Amo\Oauthapi) { 39 | $query = new Api\Oauth\Query($this->service->instance, get_class($this->service)); 40 | } else { 41 | $query = new Api\Query($this->service->instance, get_class($this->service)); 42 | } 43 | $query->setUrl($this->url); 44 | $query->setArgs( 45 | array_merge($this->service->api_args, $this->args, $arg) 46 | ); 47 | if ($this->service->modified_from) { 48 | $d = \DateTime::createFromFormat('U', $this->service->modified_from, new \DateTimeZone($this->service->instance->getAuth('timezone'))); 49 | $d->setTimezone(new \DateTimeZone("UTC")); 50 | $query->setHeader( 51 | 'If-Modified-Since', $d->format('D, d M Y H:i:s T') 52 | ); 53 | } 54 | if ($this->service->canCache()) { 55 | if ($cached = $this->service->instance->queries->getCached($query->generateHash())) { 56 | return $this->parseResponse($cached); 57 | } 58 | } 59 | $query->execute(); 60 | return $this->parseResponse( 61 | $query 62 | ); 63 | } 64 | 65 | /** 66 | * Parse api response 67 | * @param Query $query 68 | * @return Collection 69 | */ 70 | protected function parseResponse(QueryModel &$query) 71 | { 72 | $collection_class = $this->service->entity_collection; 73 | $collection = new $collection_class([], $this->service); 74 | $model_class = $this->service->entity_model; 75 | 76 | if ($query->response->getCode() == 204) { 77 | return $collection; 78 | } 79 | if (!$response = $query->response->parseJson()) { 80 | throw new \Exception('Invalid API response (non JSON), code: '.$query->response->getCode(), $query->response->getCode()); 81 | } 82 | if (!empty($response->_embedded->errors)) { 83 | throw new \Exception('API response errors: '.json_encode($response->_embedded->errors, JSON_UNESCAPED_UNICODE), $query->response->getCode()); 84 | } 85 | if (!isset($response->_embedded->items)) { 86 | if (isset($response->error)) { 87 | throw new \Exception('API response error (code: '.$query->response->getCode().') '.$response->error, $query->response->getCode()); 88 | } 89 | if (isset($response->title) && isset($response->detail)) { 90 | throw new \Exception('API response error (code: '.$query->response->getCode().'), '.$response->detail, $query->response->getCode()); 91 | } 92 | if (!in_array($query->response->getCode(), [200, 204])) { 93 | if (isset($response->response) && isset($response->response->error)) { 94 | throw new \Exception('Invalid API response ('.$this->service->entity_key.': items not found) - '.strval($response->response->error), $query->response->getCode()); 95 | } 96 | throw new \Exception('Invalid API response ('.$this->service->entity_key.': items not found), code: '.$query->response->getCode(), $query->response->getCode()); 97 | } 98 | } else { 99 | foreach ($response->_embedded->items as $raw) { 100 | $collection->push( 101 | new $model_class($raw, $this->service, $query) 102 | ); 103 | } 104 | if (count($response->_embedded->items) > 1) { 105 | $response = null; 106 | $query->clear(); 107 | } 108 | } 109 | return $collection; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/Base/Methods/LimitedList.php: -------------------------------------------------------------------------------- 1 | service->entity_collection; 17 | $collection = new $collection_class([], $this->service); 18 | $limit_offset = 0; 19 | do { 20 | $result = $this->call( 21 | array_merge($arg, ['limit_rows' => $this->service->limit_rows, 'limit_offset' => $limit_offset]) 22 | ); 23 | $result->each(function(&$item) use(&$collection) { 24 | $collection->push($item); 25 | }); 26 | $limit_offset+= $this->service->limit_rows; 27 | } while ( 28 | $result->count() == $this->service->limit_rows && ($this->service->max_rows === 0 || ($collection->count()+$this->service->limit_rows) <= $this->service->max_rows) 29 | ); 30 | $result = null; 31 | return $collection; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Base/Methods/Method.php: -------------------------------------------------------------------------------- 1 | service = $service; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Base/Methods/Post.php: -------------------------------------------------------------------------------- 1 | service->instance instanceOf \Ufee\Amo\Oauthapi) { 23 | $query = new Api\Oauth\Query($this->service->instance, get_class($this->service)); 24 | } else { 25 | $query = new Api\Query($this->service->instance, get_class($this->service)); 26 | } 27 | $query->setUrl($this->url); 28 | $query->setMethod('POST'); 29 | $query->setPostData($post_data); 30 | $query->setArgs( 31 | array_merge($this->service->api_args, $this->args, $arg) 32 | ); 33 | $query->execute(); 34 | return $this->parseResponse( 35 | $query 36 | ); 37 | } 38 | 39 | /** 40 | * Parse api response 41 | * @param Query $query 42 | * @return Collection 43 | */ 44 | protected function parseResponse(QueryModel &$query) 45 | { 46 | if (!$response = $query->response->parseJson()) { 47 | throw new \Exception('Invalid API response (non JSON), code: '.$query->response->getCode(), $query->response->getCode()); 48 | } 49 | if (!isset($response->_embedded->items)) { 50 | if (isset($response->error)) { 51 | throw new \Exception('API response error (code: '.$query->response->getCode().') '.$response->error, $query->response->getCode()); 52 | } 53 | if (isset($response->title) && isset($response->detail)) { 54 | throw new \Exception('API response error (code: '.$query->response->getCode().'), '.$response->detail, $query->response->getCode()); 55 | } 56 | if (!in_array($query->response->getCode(), [200, 204])) { 57 | if (isset($response->response) && isset($response->response->error)) { 58 | throw new \Exception('Invalid API response ('.$this->service->entity_key.': items not found) - '.strval($response->response->error), $query->response->getCode()); 59 | } 60 | throw new \Exception('Invalid API response ('.$this->service->entity_key.': items not found), code: '.$query->response->getCode(), $query->response->getCode()); 61 | } 62 | } 63 | if (!empty($response->_embedded->errors)) { 64 | throw new \Exception('API response errors: '.json_encode($response->_embedded->errors, JSON_UNESCAPED_UNICODE), $query->response->getCode()); 65 | } 66 | $result = new Collection(); 67 | if (isset($response->_embedded->items)) { 68 | foreach ($response->_embedded->items as $raw) { 69 | if (is_array($raw)) { 70 | foreach ($raw as $raw_item) { 71 | $raw_item->{'query_hash'} = $query->generateHash(); 72 | $result->push($raw_item); 73 | } 74 | } else if (is_object($raw)) { 75 | $raw->{'query_hash'} = $query->generateHash(); 76 | $result->push($raw); 77 | } 78 | 79 | } 80 | } 81 | return $result; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/Base/Models/CustomField/BirthDayField.php: -------------------------------------------------------------------------------- 1 | getValue()) { 16 | return null; 17 | } 18 | $date = new \DateTime($date, new \DateTimeZone($this->field->instance()->getAuth('timezone'))); 19 | return $date->format($format); 20 | } 21 | 22 | /** 23 | * Get date timestamp 24 | * @return integer 25 | */ 26 | public function getTimestamp() 27 | { 28 | if (!$date = $this->getValue()) { 29 | return null; 30 | } 31 | $date = new \DateTime($date, new \DateTimeZone($this->field->instance()->getAuth('timezone'))); 32 | return $date->getTimestamp(); 33 | } 34 | 35 | /** 36 | * Set date timestamp 37 | * @param integer $stamp 38 | */ 39 | public function setTimestamp($stamp) 40 | { 41 | return $this->setValue(date('Y-m-d H:i:s', $stamp)); 42 | } 43 | 44 | /** 45 | * Set date 46 | * @param string $date 47 | */ 48 | public function setDate($date) 49 | { 50 | return $this->setValue($date); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Base/Models/CustomField/CategoryField.php: -------------------------------------------------------------------------------- 1 | getValues(); 16 | } 17 | 18 | /** 19 | * Get cf values 20 | * @return mixed 21 | */ 22 | public function getValues() 23 | { 24 | if (!isset($this->values[0])) { 25 | return null; 26 | } 27 | return $this->values; 28 | } 29 | 30 | /** 31 | * Set value 32 | * @param array $values 33 | */ 34 | public function setValue($values) 35 | { 36 | return $this->setValues($values); 37 | } 38 | 39 | /** 40 | * Set values 41 | * @param array $values 42 | */ 43 | public function setValues($values) 44 | { 45 | $this->values = $values; 46 | } 47 | } -------------------------------------------------------------------------------- /src/Base/Models/CustomField/CheckboxField.php: -------------------------------------------------------------------------------- 1 | values as $setted) { 17 | $values[]= (int)$setted->value; 18 | } 19 | return $values; 20 | } 21 | 22 | /** 23 | * Set cf value to 1 24 | */ 25 | public function enable() 26 | { 27 | return $this->setValue(1); 28 | } 29 | 30 | /** 31 | * Set cf value to 0 32 | */ 33 | public function disable() 34 | { 35 | return $this->setValue(0); 36 | } 37 | 38 | /** 39 | * Has checked box 40 | */ 41 | public function hasChecked() 42 | { 43 | return (bool)$this->getValue(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Base/Models/CustomField/DateField.php: -------------------------------------------------------------------------------- 1 | getValue()) { 17 | return null; 18 | } 19 | if (is_null($timezone)) { 20 | $timezone = $this->field->instance()->getAuth('timezone'); 21 | } 22 | return new \DateTime($date, new \DateTimeZone($timezone)); 23 | } 24 | 25 | /** 26 | * Get formatted date 27 | * @param string $format - Y-m-d 28 | * @param string|null $timezone - Europe/Moscow 29 | * @return string 30 | */ 31 | public function format($format, $timezone = null) 32 | { 33 | if (!$date = $this->getValue()) { 34 | return null; 35 | } 36 | return $this->getDateTime($timezone)->format($format); 37 | } 38 | 39 | /** 40 | * Get date timestamp 41 | * @param string|null $timezone - Europe/Moscow ... 42 | * @return integer 43 | */ 44 | public function getTimestamp($timezone = null) 45 | { 46 | if (!$date = $this->getValue()) { 47 | return null; 48 | } 49 | return $this->getDateTime($timezone)->getTimestamp(); 50 | } 51 | 52 | /** 53 | * Set date timestamp 54 | * @param integer $stamp 55 | */ 56 | public function setTimestamp($stamp) 57 | { 58 | return $this->setValue(date('Y-m-d H:i:s', $stamp)); 59 | } 60 | 61 | /** 62 | * Set date 63 | * @param string $date 64 | */ 65 | public function setDate($date) 66 | { 67 | return $this->setValue($date); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Base/Models/CustomField/EmailField.php: -------------------------------------------------------------------------------- 1 | values as $setted) { 17 | $values[]= $setted->value; 18 | } 19 | return $values; 20 | } 21 | 22 | /** 23 | * Set cf value 24 | * @param string $value 25 | * @param string|integer $enum_key 26 | */ 27 | public function setValue($value, $enum_key = 'Work') 28 | { 29 | if (is_numeric($enum_key) && isset($this->field->enums->{$enum_key})) { 30 | $enum = $enum_key; 31 | $enum_key = $this->field->enums->{$enum_key}; 32 | } else { 33 | $enum_key = mb_strtoupper($enum_key); 34 | $enum = array_search($enum_key, (array)$this->field->enums); 35 | } 36 | if ($enum === false) { 37 | throw new \Exception('Invalid enum: "'.$enum_key.'" for cfield "'.$this->name.'" (enum not found)'); 38 | } 39 | if (is_numeric($enum)) { 40 | $enum = intval($enum); 41 | } 42 | $value = trim((string)$value); 43 | $new_values = []; 44 | foreach ($this->values as $setted) { 45 | if ($value == $setted->value) { 46 | continue; 47 | } 48 | $new_values[]= (object)[ 49 | 'value' => $setted->value, 'enum' => $setted->enum 50 | ]; 51 | } 52 | $new_values[]= (object)[ 53 | 'value' => $value, 'enum' => $enum 54 | ]; 55 | $this->values = $new_values; 56 | return $this; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Base/Models/CustomField/EntityField.php: -------------------------------------------------------------------------------- 1 | values[0])) { 31 | return null; 32 | } 33 | return $this->values[0]->value; 34 | } 35 | 36 | /** 37 | * Get cf values 38 | * @return array 39 | */ 40 | public function getValues() 41 | { 42 | $values = []; 43 | foreach ($this->values as $setted) { 44 | if (property_exists($setted, 'value')) { 45 | $values[]= $setted->value; 46 | } 47 | } 48 | return $values; 49 | } 50 | 51 | /** 52 | * Set cf values 53 | * @param mixed $value value 54 | */ 55 | public function setValue($value) 56 | { 57 | $this->values = [ 58 | (object)['value' => $value] 59 | ]; 60 | return $this; 61 | } 62 | 63 | /** 64 | * Reset cf value 65 | */ 66 | public function reset() 67 | { 68 | $this->values = []; 69 | return $this; 70 | } 71 | 72 | /** 73 | * Get cf raw 74 | * @return array 75 | */ 76 | public function getRaw() 77 | { 78 | $raw = [ 79 | 'id' => $this->id, 80 | 'name' => $this->name, 81 | 'code' => $this->code, 82 | 'values' => $this->values, 83 | 'is_system' => $this->field->is_system 84 | ]; 85 | if (empty($raw['code'])) { 86 | unset($raw['code']); 87 | } 88 | return $raw; 89 | } 90 | 91 | /** 92 | * Get cf raw 93 | * @return array 94 | */ 95 | public function getApiRaw() 96 | { 97 | return [ 98 | 'id' => $this->id, 99 | 'values' => $this->getApiRawValues() 100 | ]; 101 | } 102 | 103 | /** 104 | * Get cf raw values 105 | * @return array 106 | */ 107 | public function getApiRawValues() 108 | { 109 | return $this->values; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/Base/Models/CustomField/FileField.php: -------------------------------------------------------------------------------- 1 | values as $setted) { 17 | if (!isset($values[$setted->enum])) { 18 | $values[$setted->enum] = []; 19 | } 20 | $values[$setted->enum][]= $setted->value; 21 | } 22 | return $values; 23 | } 24 | 25 | /** 26 | * Set cf value 27 | * @param string $value 28 | * @param string $enum_key 29 | */ 30 | public function setValue($value, $enum_key = 'Other') 31 | { 32 | $enum_key = mb_strtoupper($enum_key); 33 | $enum = array_search($enum_key, (array)$this->field->enums); 34 | if ($enum === false) { 35 | throw new \Exception('Invalid enum: "'.$enum_key.'" for cfield "'.$this->name.'" (enum not found)'); 36 | } 37 | if (is_numeric($enum)) { 38 | $enum = intval($enum); 39 | } 40 | $new_values = []; 41 | foreach ($this->values as $setted) { 42 | if ($value == $setted->value) { 43 | continue; 44 | } 45 | $new_values[]= (object)[ 46 | 'value' => $setted->value, 'enum' => $setted->enum 47 | ]; 48 | } 49 | $new_values[]= (object)[ 50 | 'value' => $value, 'enum' => $enum 51 | ]; 52 | $this->values = $new_values; 53 | return $this; 54 | } 55 | } -------------------------------------------------------------------------------- /src/Base/Models/CustomField/ItemsField.php: -------------------------------------------------------------------------------- 1 | values[0]) || !isset($this->values[0][0])) { 16 | return null; 17 | } 18 | return $this->values[0][0]; 19 | } 20 | 21 | /** 22 | * Get cf values 23 | * @return array 24 | */ 25 | public function getValues() 26 | { 27 | $values = []; 28 | foreach ($this->values as $setted) { 29 | foreach ($setted as $val) { 30 | $values[]= $val; 31 | } 32 | } 33 | return $values; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Base/Models/CustomField/JurField.php: -------------------------------------------------------------------------------- 1 | values[0])) { 16 | return (object)[ 17 | 'name' => '', 18 | 'entity_type' => '', 19 | 'vat_id' => '', 20 | 'tax_registration_reason_code' => '', 21 | 'address' => '', 22 | 'kpp' => '', 23 | 'external_uid' => '' 24 | ]; 25 | } 26 | return $this->values[0]->value; 27 | } 28 | 29 | 30 | /** 31 | * Get cf values 32 | * @return array 33 | */ 34 | public function getValues() 35 | { 36 | return (array)$this->getValue(); 37 | } 38 | 39 | /** 40 | * Set client name 41 | * @param string $value 42 | */ 43 | public function setName($value) 44 | { 45 | $setted = $this->getValue(); 46 | $setted->name = $value; 47 | return $this->setValue($setted); 48 | } 49 | 50 | /** 51 | * Set client type 52 | * @param integer $value 53 | */ 54 | public function setType($value) 55 | { 56 | $setted = $this->getValue(); 57 | $setted->entity_type = $value; 58 | return $this->setValue($setted); 59 | } 60 | 61 | /** 62 | * Set cf value 63 | * @param string $value 64 | */ 65 | public function setAddress($value) 66 | { 67 | $setted = $this->getValue(); 68 | $setted->address = $value; 69 | return $this->setValue($setted); 70 | } 71 | 72 | /** 73 | * Set client INN 74 | * @param integer $value 75 | */ 76 | public function setInn($value) 77 | { 78 | $setted = $this->getValue(); 79 | $setted->vat_id = $value; 80 | return $this->setValue($setted); 81 | } 82 | 83 | /** 84 | * Set client KPP 85 | * @param integer $value 86 | */ 87 | public function setKpp($value) 88 | { 89 | $setted = $this->getValue(); 90 | $setted->kpp = $value; 91 | return $this->setValue($setted); 92 | } 93 | 94 | /** 95 | * Set external uid 96 | * @param integer $value 97 | */ 98 | public function externalUid($value) 99 | { 100 | $setted = $this->getValue(); 101 | $setted->external_uid = $value; 102 | return $this->setValue($setted); 103 | } 104 | 105 | /** 106 | * Set tax registration reason code 107 | * @param integer $value 108 | */ 109 | public function taxRegistrationReasonCode($value) 110 | { 111 | $setted = $this->getValue(); 112 | $setted->tax_registration_reason_code = $value; 113 | return $this->setValue($setted); 114 | } 115 | 116 | /** 117 | * Get cf raw values 118 | * @return array 119 | */ 120 | public function getApiRawValues() 121 | { 122 | return [ 123 | (object)['value' => $this->getValue()] 124 | ]; 125 | } 126 | } -------------------------------------------------------------------------------- /src/Base/Models/CustomField/MultiSelectField.php: -------------------------------------------------------------------------------- 1 | values as $setted) { 17 | $values[]= $setted->value; 18 | } 19 | return $values; 20 | } 21 | 22 | /** 23 | * Get cf enums 24 | * @return array 25 | */ 26 | public function getEnums() 27 | { 28 | $enums = []; 29 | foreach ($this->values as $setted) { 30 | $enums[]= $setted->enum; 31 | } 32 | return $enums; 33 | } 34 | 35 | /** 36 | * Reset cf values 37 | */ 38 | public function reset() 39 | { 40 | $this->values = []; 41 | return $this; 42 | } 43 | 44 | /** 45 | * Set cf value 46 | * @param string $value 47 | */ 48 | public function setValue($value) 49 | { 50 | return $this->setValues([$value]); 51 | } 52 | 53 | /** 54 | * Set cf values 55 | * @param array $values 56 | */ 57 | public function setValues(Array $values) 58 | { 59 | $values = array_unique(array_merge($this->getValues(), $values)); 60 | $enums = []; 61 | foreach($values as $value) { 62 | $value = htmlspecialchars($value, ENT_COMPAT); 63 | $enum = array_search($value, get_object_vars($this->field->enums)); 64 | if ($enum === false) { 65 | throw new \Exception('Invalid value: "'.$value.'" for cfield "'.$this->name.'" (enum not found)'); 66 | } 67 | $enums[]= $enum; 68 | } 69 | return $this->setEnums($enums); 70 | } 71 | 72 | /** 73 | * Set cf enum 74 | * @param integer $enum 75 | */ 76 | public function setEnum($enum) 77 | { 78 | return $this->setEnums([$enum]); 79 | } 80 | 81 | /** 82 | * Set cf enums 83 | * @param array $enums 84 | */ 85 | public function setEnums(Array $enums) 86 | { 87 | $enums = array_unique(array_merge($this->getEnums(), $enums)); 88 | $new_values = []; 89 | foreach ($enums as $enum) { 90 | if (!array_key_exists($enum, get_object_vars($this->field->enums))) { 91 | throw new \Exception('Invalid enum: "'.$enum.'" for cfield "'.$this->name.'" (not found)'); 92 | } 93 | $new_values[$enum]= (object)[ 94 | 'value' => $this->field->enums->{$enum}, 95 | 'enum' => $enum 96 | ]; 97 | } 98 | $this->values = array_values($new_values); 99 | return $this; 100 | } 101 | 102 | /** 103 | * Get cf raw values 104 | * @return array 105 | */ 106 | public function getApiRawValues() 107 | { 108 | return $this->getEnums(); 109 | } 110 | } -------------------------------------------------------------------------------- /src/Base/Models/CustomField/MultiTextField.php: -------------------------------------------------------------------------------- 1 | values[0])) { 16 | return null; 17 | } 18 | return $this->values[0]->value; 19 | } 20 | 21 | /** 22 | * Get cf values 23 | * @return array 24 | */ 25 | public function getValues() 26 | { 27 | $values = []; 28 | foreach ($this->values as $setted) { 29 | $values[]= $setted->value; 30 | } 31 | return $values; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Base/Models/CustomField/OrgField.php: -------------------------------------------------------------------------------- 1 | '', 11 | 'entity_type' => '', 12 | 'vat_id' => '', 13 | 'tax_registration_reason_code' => '', 14 | 'address' => '', 15 | 'kpp' => '', 16 | 'bank_code' => '', 17 | 'external_uid' => '', 18 | 'line1' => '', 19 | 'line2' => '', 20 | 'city' => '', 21 | 'state' => '', 22 | 'zip' => '', 23 | 'country' => '' 24 | ]; 25 | 26 | /** 27 | * Get cf value 28 | * @return mixed 29 | */ 30 | public function getValue() 31 | { 32 | if (!isset($this->values[0])) { 33 | return null; 34 | } 35 | return $this->values[0]->value->name; 36 | } 37 | 38 | /** 39 | * Get cf values 40 | * @return array 41 | */ 42 | public function getValues() 43 | { 44 | if (!isset($this->values[0])) { 45 | return null; 46 | } 47 | return (array)$this->values[0]->value; 48 | } 49 | 50 | /** 51 | * Add organization 52 | * @param array $value 53 | */ 54 | public function addValue(array $value) 55 | { 56 | $new_values = $this->values; 57 | $org = static::ORG_STRUCTURE; 58 | foreach ($org as $key=>$val) { 59 | if (isset($value[$key])) { 60 | $org[$key] = $value[$key]; 61 | } 62 | } 63 | $new_values[]= (object)[ 64 | 'value' => $org 65 | ]; 66 | $this->values = $new_values; 67 | return $this; 68 | } 69 | 70 | /** 71 | * Set organization 72 | * @param array $value 73 | */ 74 | public function setValue($value) 75 | { 76 | $org = static::ORG_STRUCTURE; 77 | foreach ($org as $key=>$val) { 78 | if (isset($value[$key])) { 79 | $org[$key] = $value[$key]; 80 | } 81 | } 82 | $this->values = [ 83 | (object)[ 84 | 'value' => (object)$org 85 | ] 86 | ]; 87 | } 88 | 89 | /** 90 | * Remove organization 91 | * @param string $key 92 | * @param string $value 93 | */ 94 | public function removeBy($key, $value) 95 | { 96 | $new_values = []; 97 | foreach ($this->values as $i=>$setted) { 98 | $org = (array)$setted->value; 99 | if (!isset($org[$key]) || $org[$key] != $value) { 100 | $new_values[]= $setted; 101 | } 102 | } 103 | $this->values = $new_values; 104 | return $this; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/Base/Models/CustomField/PhoneField.php: -------------------------------------------------------------------------------- 1 | values as $setted) { 17 | $values[]= $setted->value; 18 | } 19 | return $values; 20 | } 21 | 22 | /** 23 | * Set cf value 24 | * @param string $value 25 | * @param string|integer $enum_key 26 | */ 27 | public function setValue($value, $enum_key = 'Work') 28 | { 29 | if (is_numeric($enum_key) && isset($this->field->enums->{$enum_key})) { 30 | $enum = $enum_key; 31 | $enum_key = $this->field->enums->{$enum_key}; 32 | } else { 33 | $enum_key = mb_strtoupper($enum_key); 34 | $enum = array_search($enum_key, (array)$this->field->enums); 35 | } 36 | if ($enum === false) { 37 | throw new \Exception('Invalid enum: "'.$enum_key.'" for cfield "'.$this->name.'" (enum not found)'); 38 | } 39 | if (is_numeric($enum)) { 40 | $enum = intval($enum); 41 | } 42 | $value = trim((string)$value); 43 | $new_values = []; 44 | foreach ($this->values as $setted) { 45 | if ($value == $setted->value) { 46 | continue; 47 | } 48 | $new_values[]= (object)[ 49 | 'value' => $setted->value, 'enum' => $setted->enum 50 | ]; 51 | } 52 | $new_values[]= (object)[ 53 | 'value' => $value, 'enum' => $enum 54 | ]; 55 | $this->values = $new_values; 56 | return $this; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Base/Models/CustomField/RadioButtonField.php: -------------------------------------------------------------------------------- 1 | values[0])) { 16 | return null; 17 | } 18 | return $this->values[0]->enum; 19 | } 20 | 21 | /** 22 | * Set cf value 23 | * @param string $value 24 | */ 25 | public function setValue($value) 26 | { 27 | $value = htmlspecialchars($value, ENT_COMPAT); 28 | $enum = array_search($value, get_object_vars($this->field->enums)); 29 | if ($enum === false) { 30 | throw new \Exception('Invalid value: "'.$value.'" for cfield "'.$this->name.'" (enum not found)'); 31 | } 32 | $this->values = [ 33 | (object)['value' => $value, 'enum' => $enum] 34 | ]; 35 | return $this; 36 | } 37 | 38 | /** 39 | * Set cf enum 40 | * @param integer $enum 41 | */ 42 | public function setEnum($enum) 43 | { 44 | $enums = get_object_vars($this->field->enums); 45 | if (!array_key_exists($enum, $enums)) { 46 | throw new \Exception('Invalid enum: "'.$enum.'" for cfield "'.$this->name.'" (not found)'); 47 | } 48 | $this->values = [ 49 | (object)['value' => $enums[$enum], 'enum' => $enum] 50 | ]; 51 | return $this; 52 | } 53 | 54 | /** 55 | * Get cf raw values 56 | * @return array 57 | */ 58 | public function getApiRawValues() 59 | { 60 | return [ 61 | ['value' => $this->getEnum()] 62 | ]; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Base/Models/CustomField/SmartAddressField.php: -------------------------------------------------------------------------------- 1 | values as $setted) { 17 | if (property_exists($setted, 'subtype')) { 18 | $values[$setted->subtype]= $setted->value; 19 | } 20 | } 21 | return $values; 22 | } 23 | 24 | /** 25 | * Set index 26 | * @param string $value 27 | */ 28 | public function setCountry($value) 29 | { 30 | return $this->setBySubtype(6, $value); 31 | } 32 | 33 | /** 34 | * Set region 35 | * @param string $value 36 | */ 37 | public function setRegion($value) 38 | { 39 | return $this->setBySubtype(4, $value); 40 | } 41 | 42 | /** 43 | * Set city 44 | * @param string $value 45 | */ 46 | public function setCity($value) 47 | { 48 | return $this->setBySubtype(3, $value); 49 | } 50 | 51 | /** 52 | * Set index 53 | * @param string $value 54 | */ 55 | public function setIndex($value) 56 | { 57 | return $this->setBySubtype(5, $value); 58 | } 59 | 60 | /** 61 | * Set address 62 | * @param string $value 63 | */ 64 | public function setAddress($value) 65 | { 66 | return $this->setBySubtype(1, $value); 67 | } 68 | 69 | /** 70 | * Set address living 71 | * @param string $value 72 | */ 73 | public function setLive($value) 74 | { 75 | return $this->setBySubtype(2, $value); 76 | } 77 | 78 | /** 79 | * Set by subtype 80 | * @param integer $subtype 81 | * @param string $value 82 | */ 83 | public function setBySubtype($subtype, $value) 84 | { 85 | $values = []; 86 | foreach ($this->values as $setted) { 87 | $values[$setted->subtype] = $setted; 88 | } 89 | $values[$subtype] = (object)[ 90 | 'value' => $value, 'subtype' => $subtype 91 | ]; 92 | $this->values = $values; 93 | return $this; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/Base/Models/CustomField/StreetAddressField.php: -------------------------------------------------------------------------------- 1 | system as $field_key) { 46 | $this->attributes[$field_key] = null; 47 | } 48 | foreach ($this->hidden as $field_key) { 49 | $this->attributes[$field_key] = null; 50 | } 51 | $this->attributes['account_id'] = $instance->getAuth('id'); 52 | $this->attributes['service'] = $service_class; 53 | $this->attributes['retry'] = true; 54 | $this->attributes['retries'] = 0; 55 | $this->_boot(); 56 | } 57 | 58 | /** 59 | * Set query curl 60 | * @return static 61 | */ 62 | public function setCurl() 63 | { 64 | $instance = $this->instance(); 65 | $this->attributes['curl'] = \curl_init(); 66 | curl_setopt_array($this->curl, [ 67 | CURLOPT_AUTOREFERER => true, 68 | CURLOPT_USERAGENT => $instance->getAuth('user_agent'), 69 | CURLOPT_SSL_VERIFYHOST => 2, 70 | CURLOPT_SSL_VERIFYPEER => 1, 71 | CURLOPT_RETURNTRANSFER => true, 72 | CURLOPT_FOLLOWLOCATION => true, 73 | CURLOPT_CONNECTTIMEOUT => 15, 74 | CURLOPT_TIMEOUT => 30, 75 | CURLOPT_HEADER => false, 76 | CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2 77 | ]); 78 | if ($interface = $instance->queries->getInterface()) { 79 | curl_setopt($this->curl, CURLOPT_INTERFACE, $interface); 80 | } 81 | return $this; 82 | } 83 | 84 | /** 85 | * DEBUG curl query 86 | * @param resource $fp - fopen file 87 | * @return Query 88 | */ 89 | public function verbose($fp) 90 | { 91 | curl_setopt($this->curl, CURLOPT_VERBOSE, 1); 92 | curl_setopt($this->curl, CURLOPT_STDERR, $fp); 93 | return $this; 94 | } 95 | 96 | /** 97 | * Generate query hash 98 | * @return string 99 | */ 100 | public function generateHash() 101 | { 102 | $args = $this->args; 103 | unset($args['USER_LOGIN'], $args['USER_HASH']); 104 | return $this->attributes['hash'] = md5( 105 | $this->instance()->getAuth('domain'). 106 | $this->instance()->getAuth('client_id'). 107 | $this->instance()->getAuth('zone'). 108 | $this->method. 109 | json_encode($args). 110 | json_encode($this->post_data). 111 | json_encode($this->json_data) 112 | ); 113 | } 114 | 115 | /** 116 | * Clear query cache 117 | * @return QueryModel 118 | */ 119 | public function clearCache() 120 | { 121 | return $this->instance()->queries->clearQueryCache($this); 122 | } 123 | 124 | /** 125 | * Get Oauthapi instance 126 | * @return Oauthapi 127 | */ 128 | public function instance() 129 | { 130 | return Oauthapi::getInstance($this->account_id); 131 | } 132 | } -------------------------------------------------------------------------------- /src/Base/Models/Traits/CatalogElements.php: -------------------------------------------------------------------------------- 1 | service->instance->catalogElements()->create(); 16 | $element->catalog_id = $this->id; 17 | return $element; 18 | } 19 | 20 | /** 21 | * Linked elements get method 22 | * @return CatalogElementsList 23 | */ 24 | public function elements() 25 | { 26 | $service = $this->service->instance->catalogElements()->where('catalog_id', $this->id); 27 | return $service; 28 | } 29 | 30 | /** 31 | * Protect elements access 32 | * @param mixed $elements attribute 33 | * @return CatalogElementsCollection 34 | */ 35 | protected function elements_access($elements) 36 | { 37 | if (is_null($this->attributes['elements'])) { 38 | $this->attributes['elements'] = $this->elements()->recursiveCall(); 39 | } 40 | return $this->attributes['elements']; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Base/Models/Traits/EntityDetector.php: -------------------------------------------------------------------------------- 1 | id; 21 | } 22 | if (is_array($entity)) { 23 | return $entity['id']; 24 | } 25 | return null; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Base/Models/Traits/LinkedCatalogElements.php: -------------------------------------------------------------------------------- 1 | catalog_elements_id; 19 | foreach ($values as $k=>$v) { 20 | if (!is_array($v)) { 21 | unset($values[$k]); 22 | } 23 | } 24 | if (!array_key_exists($catalog_id, $values)) { 25 | $values[$catalog_id] = []; 26 | } 27 | $values[$catalog_id][$element_id] = $count; 28 | $this->catalog_elements_id = $values; 29 | return $this; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Base/Models/Traits/LinkedCompany.php: -------------------------------------------------------------------------------- 1 | getIdFrom($company)) { 17 | if ($company instanceof \Ufee\Amo\Models\Company) { 18 | $this->attributes['company'] = $company; 19 | } 20 | $this->company_id = $company_id; 21 | } 22 | return $this; 23 | } 24 | 25 | /** 26 | * Has linked company 27 | * @param mixed $company 28 | * @return bool 29 | */ 30 | public function hasCompany($company = null) 31 | { 32 | if ($company_id = $this->getIdFrom($company)) { 33 | return $this->company_id == $company_id; 34 | } 35 | return is_numeric($this->company_id) && $this->company_id > 0; 36 | } 37 | 38 | /** 39 | * Linked company get method 40 | * @return CompaniesList 41 | */ 42 | public function company() 43 | { 44 | return $this->service->instance->companies()->where('id', $this->company_id); 45 | } 46 | 47 | /** 48 | * Protect company access 49 | * @param mixed $company attribute 50 | * @return Company|null 51 | */ 52 | protected function company_access($company) 53 | { 54 | if (is_null($this->attributes['company'])) { 55 | if ($this->hasCompany()) { 56 | $this->attributes['company'] = $this->service->instance->companies()->find($this->company_id); 57 | } 58 | } 59 | return $this->attributes['company']; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Base/Models/Traits/LinkedContacts.php: -------------------------------------------------------------------------------- 1 | attachContact($contact); 18 | } 19 | return $this; 20 | } 21 | 22 | /** 23 | * Attach contact 24 | * @param mixed $contact 25 | * @return static 26 | */ 27 | public function attachContact($contact) 28 | { 29 | if ($contact_id = $this->getIdFrom($contact)) { 30 | 31 | $linked_contacts = array_merge($this->contacts_id, [$contact_id]); 32 | $this->contacts_id = array_unique($linked_contacts); 33 | 34 | if ($contact instanceof \Ufee\Amo\Models\Contact && !$this->contacts->find('id', $contact->id)->first()) { 35 | $this->contacts->push($contact); 36 | } 37 | } 38 | return $this; 39 | } 40 | 41 | /** 42 | * Has linked contacts 43 | * @param mixed $contacts 44 | * @return bool 45 | */ 46 | public function hasContacts($contacts = null) 47 | { 48 | if (!is_null($contacts)) { 49 | if (!is_array($contacts)) { 50 | $contacts = [$contacts]; 51 | } 52 | foreach ($contacts as $contact) { 53 | if (!$contact_id = $this->getIdFrom($contact)) { 54 | return false; 55 | } 56 | if (!in_array($contact_id, $this->contacts_id)) { 57 | return false; 58 | } 59 | } 60 | return true; 61 | } 62 | return count($this->contacts_id) > 0; 63 | } 64 | 65 | /** 66 | * Linked contacts get method 67 | * @return ContactsList 68 | */ 69 | public function contacts() 70 | { 71 | return $this->service->instance->contacts()->where('id', $this->contacts_id); 72 | } 73 | 74 | /** 75 | * Protect contacts access 76 | * @param mixed $contacts attribute 77 | * @return LeadCollection 78 | */ 79 | protected function contacts_access($contacts) 80 | { 81 | if (is_null($this->attributes['contacts'])) { 82 | $service = $this->service->instance->contacts(); 83 | $this->attributes['contacts'] = new \Ufee\Amo\Collections\ContactCollection([], $service); 84 | } 85 | if ($this->hasContacts()) { 86 | $can_load_contacts = []; 87 | foreach ($this->contacts_id as $contact_id) { 88 | if (!$this->attributes['contacts']->find('id', $contact_id)->first()) { 89 | $can_load_contacts[]= $contact_id; 90 | } 91 | } 92 | if (!empty($can_load_contacts)) { 93 | $this->attributes['contacts'] = $this->contacts()->call(); 94 | } 95 | } 96 | return $this->attributes['contacts']; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/Base/Models/Traits/LinkedCustomers.php: -------------------------------------------------------------------------------- 1 | attachCustomer($customer); 18 | } 19 | return $this; 20 | } 21 | 22 | /** 23 | * Attach customer 24 | * @param mixed $customer 25 | * @return static 26 | */ 27 | public function attachCustomer($customer) 28 | { 29 | if ($customer_id = $this->getIdFrom($customer)) { 30 | 31 | $linked_customers = array_merge($this->customers_id, [$customer_id]); 32 | $this->customers_id = array_unique($linked_customers); 33 | 34 | if ($customer instanceof \Ufee\Amo\Models\Customer && !$this->customers->find('id', $customer->id)->first()) { 35 | $this->customers->push($customer); 36 | } 37 | } 38 | return $this; 39 | } 40 | 41 | /** 42 | * Has linked customers 43 | * @param mixed $customers 44 | * @return bool 45 | */ 46 | public function hasCustomers($customers = null) 47 | { 48 | if (!is_null($customers)) { 49 | if (!is_array($customers)) { 50 | $customers = [$customers]; 51 | } 52 | foreach ($customers as $customer) { 53 | if (!$customer_id = $this->getIdFrom($customer)) { 54 | return false; 55 | } 56 | if (!in_array($customer_id, $this->customers_id)) { 57 | return false; 58 | } 59 | } 60 | return true; 61 | } 62 | return count($this->customers_id) > 0; 63 | } 64 | 65 | /** 66 | * Linked customers get method 67 | * @return CustomersList 68 | */ 69 | public function customers() 70 | { 71 | return $this->service->instance->customers()->where('id', $this->customers_id); 72 | } 73 | 74 | /** 75 | * Protect customers access 76 | * @param mixed $customers attribute 77 | * @return CustomerCollection 78 | */ 79 | protected function customers_access($customers) 80 | { 81 | if (is_null($this->attributes['customers'])) { 82 | $service = $this->service->instance->customers(); 83 | $this->attributes['customers'] = new \Ufee\Amo\Collections\CustomerCollection([], $service); 84 | } 85 | if ($this->hasCustomers()) { 86 | $can_load_customers = []; 87 | foreach ($this->customers_id as $customer_id) { 88 | if (!$this->attributes['customers']->find('id', $customer_id)->first()) { 89 | $can_load_customers[]= $customer_id; 90 | } 91 | } 92 | if (!empty($can_load_customers)) { 93 | $this->attributes['customers'] = $this->customers()->call(); 94 | } 95 | } 96 | return $this->attributes['customers']; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/Base/Models/Traits/LinkedLeads.php: -------------------------------------------------------------------------------- 1 | attachLead($lead); 18 | } 19 | return $this; 20 | } 21 | 22 | /** 23 | * Attach lead 24 | * @param mixed $lead 25 | * @return static 26 | */ 27 | public function attachLead($lead) 28 | { 29 | if ($lead_id = $this->getIdFrom($lead)) { 30 | 31 | $linked_leads = array_merge($this->leads_id, [$lead_id]); 32 | $this->leads_id = array_unique($linked_leads); 33 | 34 | if ($lead instanceof \Ufee\Amo\Models\Lead && !$this->leads->find('id', $lead->id)->first()) { 35 | $this->leads->push($lead); 36 | } 37 | } 38 | return $this; 39 | } 40 | 41 | /** 42 | * Has linked leads 43 | * @param mixed $leads 44 | * @return bool 45 | */ 46 | public function hasLeads($leads = null) 47 | { 48 | if (!is_null($leads)) { 49 | if (!is_array($leads)) { 50 | $leads = [$leads]; 51 | } 52 | foreach ($leads as $lead) { 53 | if (!$lead_id = $this->getIdFrom($lead)) { 54 | return false; 55 | } 56 | if (!in_array($lead_id, $this->leads_id)) { 57 | return false; 58 | } 59 | } 60 | return true; 61 | } 62 | return count($this->leads_id) > 0; 63 | } 64 | 65 | /** 66 | * Linked leads get method 67 | * @return LeadsList 68 | */ 69 | public function leads() 70 | { 71 | return $this->service->instance->leads()->where('id', $this->leads_id); 72 | } 73 | 74 | /** 75 | * Protect leads access 76 | * @param mixed $leads attribute 77 | * @return LeadCollection 78 | */ 79 | protected function leads_access($leads) 80 | { 81 | $service = $this->service->instance->leads(); 82 | if (is_null($this->attributes['leads'])) { 83 | $this->attributes['leads'] = new \Ufee\Amo\Collections\LeadCollection([], $service); 84 | } 85 | if ($this->hasLeads()) { 86 | $can_load_leads = []; 87 | foreach ($this->leads_id as $lead_id) { 88 | if (!$this->attributes['leads']->find('id', $lead_id)->first()) { 89 | $can_load_leads[]= $lead_id; 90 | } 91 | } 92 | if (!empty($can_load_leads)) { 93 | $chunks = array_chunk($this->leads_id, 400); 94 | $leads = new \Ufee\Amo\Collections\LeadCollection([], $service); 95 | 96 | foreach ($chunks as $chunk) { 97 | $part = $this->service->instance->leads()->where('id', $chunk)->call(); 98 | $leads->merge($part); 99 | } 100 | $this->attributes['leads'] = $leads; 101 | } 102 | } 103 | return $this->attributes['leads']; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/Base/Models/Traits/LinkedNotes.php: -------------------------------------------------------------------------------- 1 | service->instance->notes()->create(); 16 | $note->note_type = $type; 17 | $note->element_type = static::$_type_id; 18 | $note->element_id = $this->id; 19 | $note->responsible_user_id = $this->responsible_user_id; 20 | 21 | if (!is_null($this->attributes['notes'])) { 22 | $this->attributes['notes']->push($note); 23 | } 24 | return $note; 25 | } 26 | 27 | /** 28 | * Linked notes get method 29 | * @return NotesList 30 | */ 31 | public function notes($type = null) 32 | { 33 | $service = $this->service->instance->notes()->where('type', static::$_type)->where('element_id', $this->id); 34 | if (!is_null($type)) { 35 | $service->where('note_type', $service); 36 | } 37 | return $service; 38 | } 39 | 40 | /** 41 | * Protect notes access 42 | * @param mixed $notes attribute 43 | * @return NoteCollection 44 | */ 45 | protected function notes_access($notes) 46 | { 47 | if (is_null($this->attributes['notes'])) { 48 | $this->attributes['notes'] = $this->notes()->recursiveCall(); 49 | } 50 | return $this->attributes['notes']; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Base/Models/Traits/LinkedParents.php: -------------------------------------------------------------------------------- 1 | getIdFrom($contact)) { 18 | return false; 19 | } 20 | if ($contact_id != $this->element_id) { 21 | return false; 22 | } 23 | } 24 | return intval($this->element_type) === 1; 25 | } 26 | 27 | /** 28 | * Has linked lead 29 | * @param mixed $lead 30 | * @return bool 31 | */ 32 | public function hasLinkedLead($lead = null) 33 | { 34 | if (!is_null($lead)) { 35 | if (!$lead_id = $this->getIdFrom($lead)) { 36 | return false; 37 | } 38 | if ($lead_id != $this->element_id) { 39 | return false; 40 | } 41 | } 42 | return intval($this->element_type) === 2; 43 | } 44 | 45 | /** 46 | * Has linked company 47 | * @param mixed $company 48 | * @return bool 49 | */ 50 | public function hasLinkedCompany($company = null) 51 | { 52 | if (!is_null($company)) { 53 | if (!$company_id = $this->getIdFrom($company)) { 54 | return false; 55 | } 56 | if ($company_id != $this->element_id) { 57 | return false; 58 | } 59 | } 60 | return intval($this->element_type) === 3; 61 | } 62 | 63 | /** 64 | * Protect linkedContact access 65 | * @param mixed $linkedContact attribute 66 | * @return ContactCollection 67 | */ 68 | protected function linkedContact_access($linkedContact) 69 | { 70 | if (intval($this->element_type) !== 1) { 71 | throw new \Exception('Invalid element type: '.$this->element_type.', must be 1'); 72 | } 73 | if (is_null($this->attributes['linkedContact'])) { 74 | $this->attributes['linkedContact'] = $this->service->instance->contacts()->find($this->element_id); 75 | } 76 | return $this->attributes['linkedContact']; 77 | } 78 | 79 | /** 80 | * Protect linkedLead access 81 | * @param mixed $linkedLead attribute 82 | * @return LeadCollection 83 | */ 84 | protected function linkedLead_access($linkedLead) 85 | { 86 | if (intval($this->element_type) !== 2) { 87 | throw new \Exception('Invalid element type: '.$this->element_type.', must be 2'); 88 | } 89 | if (is_null($this->attributes['linkedLead'])) { 90 | $this->attributes['linkedLead'] = $this->service->instance->leads()->find($this->element_id); 91 | } 92 | return $this->attributes['linkedLead']; 93 | } 94 | 95 | /** 96 | * Protect linkedCompany access 97 | * @param mixed $linkedCompany attribute 98 | * @return CompanyCollection 99 | */ 100 | protected function linkedCompany_access($linkedCompany) 101 | { 102 | if (intval($this->element_type) !== 3) { 103 | throw new \Exception('Invalid element type: '.$this->element_type.', must be 3'); 104 | } 105 | if (is_null($this->attributes['linkedCompany'])) { 106 | $this->attributes['linkedCompany'] = $this->service->instance->companies()->find($this->element_id); 107 | } 108 | return $this->attributes['linkedCompany']; 109 | } 110 | 111 | /** 112 | * Get linked parent 113 | * @return Contact|Lead|Company|null 114 | */ 115 | public function getParent() 116 | { 117 | if ($this->hasLinkedLead()) { 118 | return $this->linkedLead; 119 | } 120 | if ($this->hasLinkedContact()) { 121 | return $this->linkedContact; 122 | } 123 | if ($this->hasLinkedCompany()) { 124 | return $this->linkedCompany; 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/Base/Models/Traits/LinkedPipeline.php: -------------------------------------------------------------------------------- 1 | service->account->pipelines->find('id', $this->attributes['pipeline_id'])->first(); 16 | } 17 | 18 | /** 19 | * Protect access pipeline status 20 | * @return Pipeline|null 21 | */ 22 | protected function status_access() 23 | { 24 | return $this->pipeline->statuses->find('id', $this->attributes['status_id'])->first(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Base/Models/Traits/LinkedTags.php: -------------------------------------------------------------------------------- 1 | attachTag($tag); 18 | } 19 | return $this; 20 | } 21 | 22 | /** 23 | * Attach tag 24 | * @param string $tag 25 | * @return static 26 | */ 27 | public function attachTag($tag) 28 | { 29 | if (!$this->hasTag($tag, $this->tags)) { 30 | $this->attributes['tags'][]= $tag; 31 | $this->changed[]= 'tags'; 32 | } 33 | return $this; 34 | } 35 | 36 | /** 37 | * Has isset tags 38 | * @param array $tags 39 | * @return bool 40 | */ 41 | public function hasTags(Array $tags) 42 | { 43 | foreach ($tags as $tag) { 44 | if (!$this->hasTag($tag)) { 45 | return false; 46 | } 47 | } 48 | return true; 49 | } 50 | 51 | /** 52 | * Has isset tag 53 | * @param string $tag 54 | * @return bool 55 | */ 56 | public function hasTag($tag) 57 | { 58 | return in_array($tag, $this->tags); 59 | } 60 | 61 | /** 62 | * Detach tags 63 | * @param mixed $tags 64 | * @return static 65 | */ 66 | public function detachTags($tags = null) 67 | { 68 | if (is_null($tags) && !empty($this->attributes['tags'])) { 69 | $this->attributes['tags'] = []; 70 | $this->changed[]= 'tags'; 71 | } else if(is_array($tags)) { 72 | foreach ($tags as $tag) { 73 | $this->detachTag($tag); 74 | } 75 | } 76 | return $this; 77 | } 78 | 79 | /** 80 | * Detach tag 81 | * @param string $tag 82 | * @return static 83 | */ 84 | public function detachTag($tag) 85 | { 86 | $key = array_search($tag, $this->attributes['tags']); 87 | if ($key !== false) { 88 | unset($this->attributes['tags'][$key]); 89 | $this->changed[]= 'tags'; 90 | } 91 | return $this; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/Base/Models/Traits/LinkedTasks.php: -------------------------------------------------------------------------------- 1 | service->instance->tasks()->create(); 16 | $task->task_type = $type; 17 | $task->element_type = static::$_type_id; 18 | $task->element_id = $this->id; 19 | $task->responsible_user_id = $this->responsible_user_id; 20 | 21 | if (!is_null($this->attributes['tasks'])) { 22 | $this->attributes['tasks']->push($task); 23 | } 24 | return $task; 25 | } 26 | 27 | /** 28 | * Linked tasks get method 29 | * @return TasksList 30 | */ 31 | public function tasks() 32 | { 33 | return $this->service->instance->tasks()->where('type', static::$_type)->where('element_id', $this->id); 34 | } 35 | 36 | /** 37 | * Protect tasks access 38 | * @param mixed $tasks attribute 39 | * @return TaskCollection 40 | */ 41 | protected function tasks_access($tasks) 42 | { 43 | if (is_null($this->attributes['tasks'])) { 44 | $this->attributes['tasks'] = $this->tasks()->recursiveCall(); 45 | } 46 | return $this->attributes['tasks']; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Base/Models/Traits/LinkedTransactions.php: -------------------------------------------------------------------------------- 1 | attachLead($lead); 18 | } 19 | return $this; 20 | } 21 | 22 | /** 23 | * Attach lead 24 | * @param mixed $lead 25 | * @return static 26 | */ 27 | public function attachLead($lead) 28 | { 29 | if ($lead_id = $this->getIdFrom($lead)) { 30 | 31 | $linked_leads = array_merge($this->leads_id, [$lead_id]); 32 | $this->leads_id = array_unique($linked_leads); 33 | 34 | if ($lead instanceof \Ufee\Amo\Models\Lead && !$this->leads->find('id', $lead->id)->first()) { 35 | $this->leads->push($lead); 36 | } 37 | } 38 | return $this; 39 | } 40 | 41 | /** 42 | * Has linked leads 43 | * @param mixed $leads 44 | * @return bool 45 | */ 46 | public function hasLeads($leads = null) 47 | { 48 | if (!is_null($leads)) { 49 | if (!is_array($leads)) { 50 | $leads = [$leads]; 51 | } 52 | foreach ($leads as $lead) { 53 | if (!$lead_id = $this->getIdFrom($lead)) { 54 | return false; 55 | } 56 | if (!in_array($lead_id, $this->leads_id)) { 57 | return false; 58 | } 59 | } 60 | return true; 61 | } 62 | return count($this->leads_id) > 0; 63 | } 64 | 65 | /** 66 | * Linked transactions get method 67 | * @return LeadsList 68 | */ 69 | public function transactions() 70 | { 71 | return $this->service->instance->transactions()->where('customer_id', $this->id); 72 | } 73 | 74 | /** 75 | * Protect leads access 76 | * @param mixed $leads attribute 77 | * @return LeadCollection 78 | */ 79 | protected function leads_access($leads) 80 | { 81 | if (is_null($this->attributes['leads'])) { 82 | $service = $this->service->instance->leads(); 83 | $this->attributes['leads'] = new \Ufee\Amo\Collections\LeadCollection([], $service); 84 | } 85 | if ($this->hasLeads()) { 86 | $can_load_leads = []; 87 | foreach ($this->leads_id as $lead_id) { 88 | if (!$this->attributes['leads']->find('id', $lead_id)->first()) { 89 | $can_load_leads[]= $lead_id; 90 | } 91 | } 92 | if (!empty($can_load_leads)) { 93 | $this->attributes['leads'] = $this->leads()->call(); 94 | } 95 | } 96 | return $this->attributes['leads']; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/Base/Models/Traits/LinkedUsers.php: -------------------------------------------------------------------------------- 1 | service->account->users->find('id', $this->attributes['created_by'])->first(); 16 | } 17 | 18 | /** 19 | * Protect access responsible user 20 | * @return User|null 21 | */ 22 | protected function responsibleUser_access() 23 | { 24 | return $this->service->account->users->find('id', $this->attributes['responsible_user_id'])->first(); 25 | } 26 | 27 | /** 28 | * Protect access updated user 29 | * @return User|null 30 | */ 31 | protected function updatedUser_access() 32 | { 33 | return $this->service->account->users->find('id', $this->attributes['updated_by'])->first(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Base/Models/Traits/MainContact.php: -------------------------------------------------------------------------------- 1 | getIdFrom($contact)) { 17 | return $this->main_contact_id == $contact_id; 18 | } 19 | return is_numeric($this->main_contact_id) && $this->main_contact_id > 0; 20 | } 21 | 22 | /** 23 | * Set linked main contact 24 | * @param mixed $contact 25 | * @return bool 26 | */ 27 | public function attachMainContact($contact) 28 | { 29 | $this->attachContact($contact); 30 | if ($contact_id = $this->getIdFrom($contact)) { 31 | if ($contact instanceof \Ufee\Amo\Models\Contact) { 32 | $this->attributes['contact'] = $contact; 33 | } 34 | $this->main_contact_id = $contact_id; 35 | } 36 | return $this; 37 | } 38 | 39 | /** 40 | * Protect main contact access 41 | * @param mixed $contact attribute 42 | * @return Contact|null 43 | */ 44 | protected function contact_access($contact) 45 | { 46 | if (is_null($this->attributes['contact'])) { 47 | if ($this->hasMainContact()) { 48 | $this->attributes['contact'] = $this->contacts->find('id', $this->main_contact_id)->first(); 49 | } 50 | } 51 | return $this->attributes['contact']; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Base/Services/Cached.php: -------------------------------------------------------------------------------- 1 | list->where('query', $query)->recursiveCall(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Base/Services/Service.php: -------------------------------------------------------------------------------- 1 | [], 22 | 'update' => ['id', 'updated_at'] 23 | ]; 24 | protected $client; 25 | protected $client_id; 26 | protected $entity_key = 'entitys'; 27 | protected $entity_model = '\Ufee\Amo\Base\Model'; 28 | protected $methods = []; 29 | protected $api_args = []; 30 | 31 | /** 32 | * Constructor 33 | * @param ApiClient $client 34 | */ 35 | private function __construct(ApiClient $client) 36 | { 37 | $this->client = $client; 38 | $this->client_id = $client->getAuth('id'); 39 | $this->_boot(); 40 | } 41 | 42 | /** 43 | * Service on load 44 | * @return void 45 | */ 46 | protected function _boot() 47 | { 48 | 49 | } 50 | 51 | /** 52 | * Set service instance 53 | * @param $name Service name 54 | * @param ApiClient $instance 55 | * @return Service 56 | */ 57 | public static function setInstance($name, \Ufee\Amo\ApiClient &$instance) 58 | { 59 | if (is_null($name)) { 60 | $name = lcfirst(static::getBasename()); 61 | } 62 | $key = $name.'-'.$instance->getAuth('domain').$instance->getAuth('id'); 63 | if (!isset(static::$_service_instances[$key])) { 64 | static::$_service_instances[$key] = new static($instance); 65 | } 66 | return static::getInstance($name, $instance); 67 | } 68 | 69 | /** 70 | * Get service instance 71 | * @param $name Service name 72 | * @return Service 73 | */ 74 | public static function getInstance($name, \Ufee\Amo\ApiClient &$instance) 75 | { 76 | if (is_null($name)) { 77 | $name = lcfirst(static::getBasename()); 78 | } 79 | $key = $name.'-'.$instance->getAuth('domain').$instance->getAuth('id'); 80 | if (!isset(static::$_service_instances[$key])) { 81 | return null; 82 | } 83 | return static::$_service_instances[$key]; 84 | } 85 | 86 | /** 87 | * Get class basename 88 | * @return string 89 | */ 90 | public static function getBasename() 91 | { 92 | return substr(static::class, strrpos(static::class, '\\') + 1); 93 | } 94 | 95 | /** 96 | * Get api method 97 | * @param string $target 98 | */ 99 | public function __get($target) 100 | { 101 | if (isset($this->{$target})) { 102 | return $this->{$target}; 103 | } 104 | $apiClass = is_numeric($this->client_id) ? Amoapi::class : Oauthapi::class; 105 | if ($target === 'instance') { 106 | return $this->client; 107 | } 108 | if ($target === 'account') { 109 | return $this->client->account; 110 | } 111 | if (!in_array($target, $this->methods)) { 112 | throw new \Exception('Invalid method called: '.$target); 113 | } 114 | $method_class = 'Ufee\\Amo\\Methods\\'.static::getBasename().'\\'.static::getBasename().ucfirst($target); 115 | return new $method_class($this); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/Base/Services/Traits/SearchByCustomField.php: -------------------------------------------------------------------------------- 1 | max_rows; 21 | $set_max_rows = $max_rows >= $this->limit_rows ? $max_rows+$this->limit_rows : $max_rows; 22 | $results = $this->maxRows($set_max_rows)->list->where('query', $query)->recursiveCall(); 23 | 24 | $collClass = get_class($results); 25 | $service = $results->service(); 26 | $searched = new $collClass([], $service); 27 | $results = $results->all(); 28 | 29 | foreach ($results as &$model) { 30 | $cf = null; 31 | if ($field_type == 'integer') { 32 | $cf = $model->cf()->byId($field); 33 | } elseif ($field_type == 'string') { 34 | $cf = $model->cf($field); 35 | } 36 | if (!$cf) { 37 | throw new \Exception('Custom Field not found by '.($field_type == 'integer' ? 'id' : 'name').': '.$field); 38 | } 39 | $value = trim((string)$cf->getValue()); 40 | if ($query === $value) { 41 | $searched->push($model); 42 | } 43 | $model = null; 44 | unset($model); 45 | usleep(50); 46 | } 47 | $results = null; 48 | unset($results); 49 | 50 | if ($max_rows > 0) { 51 | $searched->slice(0, $max_rows); 52 | } 53 | $this->maxRows($prev_max_rows); 54 | return $searched; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Base/Services/Traits/SearchByEmail.php: -------------------------------------------------------------------------------- 1 | max_rows; 26 | $set_max_rows = $max_rows >= $this->limit_rows ? $max_rows+$this->limit_rows : $max_rows; 27 | $results = $this->maxRows($set_max_rows)->list->where('query', $query)->recursiveCall(); 28 | 29 | $collClass = get_class($results); 30 | $service = $results->service(); 31 | $searched = new $collClass([], $service); 32 | $results = $results->all(); 33 | 34 | foreach ($results as &$model) { 35 | foreach ($model->cf($field_name)->getValues() as $value) { 36 | if ($query === $clearEmail($value)) { 37 | $searched->push($model); 38 | } 39 | } 40 | $model = null; 41 | unset($model); 42 | usleep(50); 43 | } 44 | $results = null; 45 | unset($results); 46 | 47 | if ($max_rows > 0) { 48 | $searched->slice(0, $max_rows); 49 | } 50 | $this->maxRows($prev_max_rows); 51 | return $searched; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Base/Services/Traits/SearchByName.php: -------------------------------------------------------------------------------- 1 | max_rows; 22 | $set_max_rows = $max_rows >= $this->limit_rows ? $max_rows+$this->limit_rows : $max_rows; 23 | $results = $this->maxRows($set_max_rows)->list->where('query', $query)->recursiveCall(); 24 | 25 | $collClass = get_class($results); 26 | $service = $results->service(); 27 | $searched = new $collClass([], $service); 28 | $results = $results->all(); 29 | 30 | foreach ($results as &$model) { 31 | if ($query === $clearName($model->name)) { 32 | $searched->push($model); 33 | } 34 | $model = null; 35 | unset($model); 36 | usleep(50); 37 | } 38 | $results = null; 39 | unset($results); 40 | 41 | if ($max_rows > 0) { 42 | $searched->slice(0, $max_rows); 43 | } 44 | $this->maxRows($prev_max_rows); 45 | return $searched; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Base/Services/Traits/SearchByPhone.php: -------------------------------------------------------------------------------- 1 | instance->getAuth('lang') == 'ru' ? 'Телефон' : 'Phone'; 39 | $query = $clearPhone($phone); 40 | if (strlen($query) < 6) { 41 | throw new \Exception('Invalid search phone value: '.$phone); 42 | } 43 | $prev_max_rows = $this->max_rows; 44 | $set_max_rows = $max_rows >= $this->limit_rows ? $max_rows+$this->limit_rows : $max_rows; 45 | $results = $this->maxRows($set_max_rows)->list->where('query', $query)->recursiveCall(); 46 | 47 | $collClass = get_class($results); 48 | $service = $results->service(); 49 | $searched = new $collClass([], $service); 50 | $results = $results->all(); 51 | 52 | foreach ($results as &$model) { 53 | foreach ($model->cf($field_name)->getValues() as $value) { 54 | if ($query === $clearPhone($value)) { 55 | $searched->push($model); 56 | } 57 | } 58 | $model = null; 59 | unset($model); 60 | usleep(50); 61 | } 62 | $results = null; 63 | unset($results); 64 | 65 | if ($max_rows > 0) { 66 | $searched->slice(0, $max_rows); 67 | } 68 | $this->maxRows($prev_max_rows); 69 | return $searched; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/Base/Storage/Oauth/AbstractStorage.php: -------------------------------------------------------------------------------- 1 | options = $options; 20 | } 21 | 22 | /** 23 | * Init oauth handler 24 | * @param Oauthapi $client 25 | * @return void 26 | */ 27 | public function initClient(Oauthapi $client) 28 | { 29 | $key = $client->getAuth('domain').'_'.$client->getAuth('client_id'); 30 | static::$_oauth[$key] = [ 31 | 'token_type' => '', 32 | 'expires_in' => 0, 33 | 'access_token' => '', 34 | 'refresh_token' => '', 35 | 'created_at' => 0 36 | ]; 37 | } 38 | 39 | /** 40 | * Set oauth data 41 | * @param Oauthapi $client 42 | * @param array $oauth 43 | * @return bool 44 | */ 45 | public function setOauthData(Oauthapi $client, array $oauth) 46 | { 47 | $key = $client->getAuth('domain').'_'.$client->getAuth('client_id'); 48 | if (!array_key_exists($key, static::$_oauth)) { 49 | $this->initClient($client); 50 | } 51 | static::$_oauth[$key] = $oauth; 52 | return true; 53 | } 54 | 55 | /** 56 | * Get oauth data 57 | * @param Oauthapi $client 58 | * @param string|null $field 59 | * @return array 60 | */ 61 | public function getOauthData(Oauthapi $client, $field = null) 62 | { 63 | $key = $client->getAuth('domain').'_'.$client->getAuth('client_id'); 64 | if (!array_key_exists($key, static::$_oauth)) { 65 | $this->initClient($client); 66 | } 67 | if (!is_null($field) && array_key_exists($field, static::$_oauth[$key])) { 68 | return static::$_oauth[$key][$field]; 69 | } 70 | return static::$_oauth[$key]; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Base/Storage/Oauth/FileStorage.php: -------------------------------------------------------------------------------- 1 | options['path'])) { 19 | throw new \Exception('File Storage options[path] must be string path'); 20 | } 21 | } 22 | 23 | /** 24 | * Init oauth handler 25 | * @param Oauthapi $client 26 | * @return void 27 | */ 28 | public function initClient(Oauthapi $client) 29 | { 30 | parent::initClient($client); 31 | 32 | if (!file_exists($this->options['path'].'/'.$client->getAuth('domain'))) { 33 | mkdir($this->options['path'].'/'.$client->getAuth('domain'), 0777, true); 34 | } 35 | if (file_exists($this->options['path'].'/'.$client->getAuth('domain').'/'.$client->getAuth('client_id').'.json')) { 36 | $key = $client->getAuth('domain').'_'.$client->getAuth('client_id'); 37 | static::$_oauth[$key] = json_decode(file_get_contents($this->options['path'].'/'.$client->getAuth('domain').'/'.$client->getAuth('client_id').'.json'), true); 38 | } 39 | } 40 | 41 | /** 42 | * Set oauth data 43 | * @param Oauthapi $client 44 | * @param array $oauth 45 | * @return bool 46 | */ 47 | public function setOauthData(Oauthapi $client, array $oauth) 48 | { 49 | parent::setOauthData($client, $oauth); 50 | return file_put_contents($this->options['path'].'/'.$client->getAuth('domain').'/'.$client->getAuth('client_id').'.json', json_encode($oauth)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Base/Storage/Oauth/LongTokenStorage.php: -------------------------------------------------------------------------------- 1 | options['long_token'])) { 16 | throw new \Exception('Long Token Storage options[long_token] must be string of the access token'); 17 | } 18 | if (empty($this->options['expires_in'])) { 19 | throw new \Exception('Long Token Storage options[expires_in] must be string|int that specifies the expiration date of the access token'); 20 | } 21 | } 22 | 23 | public function initClient(Oauthapi $client) 24 | { 25 | parent::initClient($client); 26 | 27 | $key = $client->getAuth('domain').'_'.$client->getAuth('client_id'); 28 | static::$_oauth[$key] = [ 29 | "token_type" => "Bearer", 30 | "expires_in" => $this->options['expires_in'], 31 | "access_token" => $this->options['long_token'], 32 | "created_at" => 1 33 | ]; 34 | } 35 | } -------------------------------------------------------------------------------- /src/Base/Storage/Oauth/MongoDbStorage.php: -------------------------------------------------------------------------------- 1 | options['collection']) || !$this->options['collection'] instanceOf \MongoDB\Collection) { 19 | throw new \Exception('MongoDB Storage options[collection] must be instance of \MongoDB\Collection'); 20 | } 21 | } 22 | 23 | /** 24 | * Init oauth handler 25 | * @param Oauthapi $client 26 | * @return void 27 | */ 28 | public function initClient(Oauthapi $client) 29 | { 30 | parent::initClient($client); 31 | 32 | $key = $client->getAuth('domain').'_'.$client->getAuth('client_id'); 33 | if ($row = $this->options['collection']->findOne(['_id' => $key])) { 34 | static::$_oauth[$key] = (array)$row->data; 35 | } 36 | } 37 | 38 | /** 39 | * Set oauth data 40 | * @param Oauthapi $client 41 | * @param array $oauth 42 | * @return void 43 | */ 44 | public function setOauthData(Oauthapi $client, array $oauth) 45 | { 46 | parent::setOauthData($client, $oauth); 47 | 48 | $result = $this->options['collection']->updateOne( 49 | ['_id' => $client->getAuth('domain').'_'.$client->getAuth('client_id')], 50 | ['$set' => ['data' => $oauth]], [ 51 | 'upsert' => true 52 | ] 53 | ); 54 | return ($result->getUpsertedCount() || $result->getMatchedCount()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Base/Storage/Oauth/RedisStorage.php: -------------------------------------------------------------------------------- 1 | options['connection']) || !$this->options['connection'] instanceOf \Redis) { 21 | throw new \Exception('Redis Storage options[connection] must be instance of \Redis'); 22 | } 23 | } 24 | 25 | /** 26 | * Init oauth handler 27 | * @param Oauthapi $client 28 | * @return void 29 | */ 30 | public function initClient(Oauthapi $client) 31 | { 32 | parent::initClient($client); 33 | 34 | $key = $client->getAuth('domain').'_'.$client->getAuth('client_id'); 35 | if ($data = $this->options['connection']->get($key)) { 36 | static::$_oauth[$key] = $data; 37 | } 38 | } 39 | 40 | /** 41 | * Set oauth data 42 | * @param Oauthapi $client 43 | * @param array $oauth 44 | * @return void 45 | */ 46 | public function setOauthData(Oauthapi $client, array $oauth) 47 | { 48 | parent::setOauthData($client, $oauth); 49 | return $this->options['connection']->setEx($client->getAuth('domain').'_'.$client->getAuth('client_id'), static::OAUTH_TTL, $oauth); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Base/Storage/Query/AbstractStorage.php: -------------------------------------------------------------------------------- 1 | client = $client; 25 | $this->options = $options; 26 | } 27 | 28 | /** 29 | * Get cached query 30 | * @param string $hash 31 | * @return QueryModel|null 32 | */ 33 | public function getCached($hash) 34 | { 35 | $query = null; 36 | if (isset($this->querys[$hash])) { 37 | $query = $this->querys[$hash]; 38 | } 39 | if ($query) { 40 | if (time()-$query->end_time > $query->getService()->cacheTime()) { 41 | unset($this->querys[$hash]); 42 | $query = null; 43 | } 44 | } 45 | return $query; 46 | } 47 | 48 | /** 49 | * Cache query 50 | * @param QueryModel $query 51 | * @return bool 52 | */ 53 | public function cacheQuery(QueryModel $query) 54 | { 55 | $this->querys[$query->hash] = $query; 56 | return true; 57 | } 58 | 59 | /** 60 | * Clear query cache 61 | * @param QueryModel $query 62 | * @return bool 63 | */ 64 | public function clearQueryCache(QueryModel $query) 65 | { 66 | if (isset($this->querys[$query->hash])) { 67 | unset($this->querys[$query->hash]); 68 | } 69 | return true; 70 | } 71 | 72 | /** 73 | * Flush cache queries 74 | * @return bool 75 | */ 76 | public function flush() 77 | { 78 | $this->querys = []; 79 | return true; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/Base/Storage/Query/FileStorage.php: -------------------------------------------------------------------------------- 1 | options['path'])) { 21 | throw new \Exception('File Storage options[path] must be string path'); 22 | } 23 | } 24 | 25 | /** 26 | * Get cached query 27 | * @param string $hash 28 | * @return QueryModel|null 29 | */ 30 | public function getCached($hash) 31 | { 32 | $query = null; 33 | $cache_path = $this->options['path'].'/'.$this->client->getAuth('domain').'_'.$hash.'.cache'; 34 | $is_file = false; 35 | 36 | if (isset($this->querys[$hash])) { 37 | $query = $this->querys[$hash]; 38 | } 39 | else if (file_exists($cache_path)) { 40 | $query = unserialize(file_get_contents($cache_path)); 41 | $is_file = true; 42 | } 43 | if ($query) { 44 | if (time()-$query->end_time > $query->getService()->cacheTime()) { 45 | unset($this->querys[$hash]); 46 | if ($is_file) { 47 | @unlink($cache_path); 48 | } 49 | $query = null; 50 | } 51 | } 52 | return $query; 53 | } 54 | 55 | /** 56 | * Cache query 57 | * @param QueryModel $query 58 | * @return bool 59 | */ 60 | public function cacheQuery(QueryModel $query) 61 | { 62 | parent::cacheQuery($query); 63 | 64 | return file_put_contents( 65 | $this->options['path'].'/'.$this->client->getAuth('domain').'_'.$query->hash.'.cache', serialize($query) 66 | ); 67 | } 68 | 69 | /** 70 | * Clear query cache 71 | * @param QueryModel $query 72 | * @return bool 73 | */ 74 | public function clearQueryCache(QueryModel $query) 75 | { 76 | parent::clearQueryCache($query); 77 | $cache_path = $this->options['path'].'/'.$this->client->getAuth('domain').'_'.$query->hash.'.cache'; 78 | 79 | if (file_exists($cache_path)) { 80 | @unlink($cache_path); 81 | } 82 | return true; 83 | } 84 | 85 | /** 86 | * Flush cache queries 87 | * @return bool 88 | */ 89 | public function flush() 90 | { 91 | parent::flush(); 92 | array_map('unlink', glob($this->options['path'].'/'.$this->client->getAuth('domain').'_*.cache')); 93 | return true; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/Base/Storage/Query/RedisStorage.php: -------------------------------------------------------------------------------- 1 | options['connection']) || !$this->options['connection'] instanceOf \Redis) { 21 | throw new \Exception('Redis Storage options[connection] must be instance of \Redis'); 22 | } 23 | } 24 | 25 | /** 26 | * Get cached query 27 | * @param string $hash 28 | * @return QueryModel|null 29 | */ 30 | public function getCached($hash) 31 | { 32 | $query = null; 33 | $cache_key = $this->client->getAuth('domain').'-cache:'.$hash; 34 | $is_redis = false; 35 | 36 | if (isset($this->querys[$hash])) { 37 | $query = $this->querys[$hash]; 38 | } 39 | else if ($query = $this->options['connection']->get($cache_key)) { 40 | $is_redis = true; 41 | } 42 | if ($query) { 43 | if (time()-$query->end_time > $query->getService()->cacheTime()) { 44 | unset($this->querys[$hash]); 45 | if ($is_redis) { 46 | $this->options['connection']->del($cache_key); 47 | } 48 | $query = null; 49 | } 50 | } 51 | return $query; 52 | } 53 | 54 | /** 55 | * Cache query 56 | * @param QueryModel $query 57 | * @return bool 58 | */ 59 | public function cacheQuery(QueryModel $query) 60 | { 61 | parent::cacheQuery($query); 62 | $cache_key = $this->client->getAuth('domain').'-cache:'.$query->hash; 63 | 64 | $ttl = $query->getService()->cacheTime(); 65 | return $this->options['connection']->setEx($cache_key, $ttl, $query); 66 | } 67 | 68 | /** 69 | * Clear query cache 70 | * @param QueryModel $query 71 | * @return bool 72 | */ 73 | public function clearQueryCache(QueryModel $query) 74 | { 75 | parent::clearQueryCache($query); 76 | $cache_key = $this->client->getAuth('domain').'-cache:'.$query->hash; 77 | 78 | $this->options['connection']->del($cache_key); 79 | return true; 80 | } 81 | 82 | /** 83 | * Flush cache queries 84 | * @return bool 85 | */ 86 | public function flush() 87 | { 88 | parent::flush(); 89 | $cache_key = $this->client->getAuth('domain').'-cache:*'; 90 | $keys = $this->options['connection']->keys($cache_key); 91 | 92 | foreach($keys as $key) { 93 | $this->options['connection']->del($key); 94 | } 95 | return true; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/Cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.htaccess 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /src/Cache/.htaccess: -------------------------------------------------------------------------------- 1 | order allow,deny 2 | deny from all -------------------------------------------------------------------------------- /src/Collections/CatalogCollection.php: -------------------------------------------------------------------------------- 1 | service->delete( 15 | $this->all() 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Collections/CollectionWrapper.php: -------------------------------------------------------------------------------- 1 | collection; 20 | } 21 | 22 | /** 23 | * Merge collections 24 | * @param Collection $collection 25 | * @return Colection 26 | */ 27 | public function merge(CollectionWrapper &$collection) 28 | { 29 | $collection_instance = $collection->collection(); 30 | return $this->collection->merge($collection_instance); 31 | } 32 | 33 | /** 34 | * Call Collection Methods 35 | * @param string $method 36 | * @param array $args 37 | */ 38 | public function __call($method, $args) 39 | { 40 | if (method_exists($this->collection, $method)) { 41 | return call_user_func_array( 42 | [$this->collection, $method], $args 43 | ); 44 | } 45 | throw new \Exception('Invalid '.static::class.' method: '.$method); 46 | } 47 | 48 | /** 49 | * Protect get fields 50 | * @param string $field 51 | */ 52 | public function __get($field) 53 | { 54 | if (!array_key_exists($field, $this->attributes)) { 55 | throw new \Exception('Invalid '.static::class.' attribute: '.$field); 56 | } 57 | return $this->attributes[$field]; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Collections/CompaniesCustomFieldCollection.php: -------------------------------------------------------------------------------- 1 | 'Ufee\Amo\Base\Models\CustomField\PhoneField', 11 | 'Phone' => 'Ufee\Amo\Base\Models\CustomField\PhoneField', 12 | 'Email' =>'Ufee\Amo\Base\Models\CustomField\EmailField', 13 | 'Мгн. сообщения' =>'Ufee\Amo\Base\Models\CustomField\ImField', 14 | 'IM' =>'Ufee\Amo\Base\Models\CustomField\ImField' 15 | ]; 16 | 17 | /** 18 | * Get cf classname 19 | * @param CustomField $cfield 20 | * @return string 21 | */ 22 | public function getClassFrom(CustomField $cfield) 23 | { 24 | if ($cfield->isSystem() && array_key_exists($cfield->name, self::SYS_FIELD_CLASSES)) { 25 | return self::SYS_FIELD_CLASSES[$cfield->name]; 26 | } 27 | return parent::getClassFrom($cfield); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Collections/CompanyCollection.php: -------------------------------------------------------------------------------- 1 | 'Ufee\Amo\Base\Models\CustomField\PhoneField', 12 | 'Phone' => 'Ufee\Amo\Base\Models\CustomField\PhoneField', 13 | 'Email' =>'Ufee\Amo\Base\Models\CustomField\EmailField', 14 | 'Мгн. сообщения' =>'Ufee\Amo\Base\Models\CustomField\ImField', 15 | 'IM' =>'Ufee\Amo\Base\Models\CustomField\ImField' 16 | ]; 17 | 18 | /** 19 | * Get cf classname 20 | * @param CustomField $cfield 21 | * @return string 22 | */ 23 | public function getClassFrom(CustomField $cfield) 24 | { 25 | if ($cfield->isSystem() && array_key_exists($cfield->name, self::SYS_FIELD_CLASSES)) { 26 | return self::SYS_FIELD_CLASSES[$cfield->name]; 27 | } 28 | return parent::getClassFrom($cfield); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Collections/CustomFieldCollection.php: -------------------------------------------------------------------------------- 1 | 'Ufee\Amo\Base\Models\CustomField\TextField', 12 | 2 => 'Ufee\Amo\Base\Models\CustomField\NumericField', 13 | 3 => 'Ufee\Amo\Base\Models\CustomField\CheckboxField', 14 | 4 => 'Ufee\Amo\Base\Models\CustomField\SelectField', 15 | 5 => 'Ufee\Amo\Base\Models\CustomField\MultiSelectField', 16 | 6 => 'Ufee\Amo\Base\Models\CustomField\DateField', 17 | 7 => 'Ufee\Amo\Base\Models\CustomField\UrlField', 18 | 8 => 'Ufee\Amo\Base\Models\CustomField\MultiTextField', 19 | 9 => 'Ufee\Amo\Base\Models\CustomField\TextareaField', 20 | 10 => 'Ufee\Amo\Base\Models\CustomField\RadioButtonField', 21 | 11 => 'Ufee\Amo\Base\Models\CustomField\StreetAddressField', 22 | 13 => 'Ufee\Amo\Base\Models\CustomField\SmartAddressField', 23 | 14 => 'Ufee\Amo\Base\Models\CustomField\BirthDayField', 24 | 15 => 'Ufee\Amo\Base\Models\CustomField\JurField', 25 | 16 => 'Ufee\Amo\Base\Models\CustomField\ItemsField', 26 | 17 => 'Ufee\Amo\Base\Models\CustomField\OrgField', 27 | 18 => 'Ufee\Amo\Base\Models\CustomField\CategoryField', 28 | 19 => 'Ufee\Amo\Base\Models\CustomField\CalendarField', 29 | 20 => 'Ufee\Amo\Base\Models\CustomField\NumericField', 30 | 21 => 'Ufee\Amo\Base\Models\CustomField\TextField', 31 | 23 => 'Ufee\Amo\Base\Models\CustomField\NumericField', 32 | 24 => 'Ufee\Amo\Base\Models\CustomField\ChainedList', 33 | 25 => 'Ufee\Amo\Base\Models\CustomField\FileField' 34 | ]; 35 | 36 | /** 37 | * Constructor 38 | * @param array $elements 39 | * @param Account $account 40 | */ 41 | public function __construct(Array $elements, \Ufee\Amo\Models\Account &$account) 42 | { 43 | $this->collection = new \Ufee\Amo\Base\Collections\Collection($elements); 44 | $client_id = $account->service->instance->getAuth('id'); 45 | $this->collection->each(function(&$item) use(&$client_id) { 46 | $item->client_id = $client_id; 47 | $item = new CustomField($item); 48 | }); 49 | $this->attributes['account'] = $account; 50 | } 51 | 52 | /** 53 | * Get cf classname 54 | * @param CustomField $cfield 55 | * @return string 56 | */ 57 | public function getClassFrom(CustomField $cfield) 58 | { 59 | if (!array_key_exists($cfield->field_type, self::FIELD_CLASSES)) { 60 | return 'Ufee\Amo\Base\Models\CustomField\EntityField'; 61 | } 62 | return self::FIELD_CLASSES[$cfield->field_type]; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Collections/CustomerCollection.php: -------------------------------------------------------------------------------- 1 | attributes['fields'] = $fields; 20 | $this->attributes['model'] = $model; 21 | } 22 | 23 | /** 24 | * Call Collection Methods 25 | * @param string $method 26 | * @param array $args 27 | */ 28 | public function __call($method, $args) 29 | { 30 | if (method_exists($this->fields, $method)) { 31 | return call_user_func_array( 32 | [$this->fields, $method], $args 33 | ); 34 | } 35 | } 36 | 37 | /** 38 | * Protect get fields 39 | * @param string $field 40 | */ 41 | public function __get($field) 42 | { 43 | if (!array_key_exists($field, $this->attributes)) { 44 | throw new \Exception('Invalid '.static::class.' attribute: '.$field); 45 | } 46 | return $this->attributes[$field]; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Collections/LeadCollection.php: -------------------------------------------------------------------------------- 1 | collection = new \Ufee\Amo\Base\Collections\Collection($elements); 17 | $this->attributes['account'] = $account; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Collections/PipelineCollection.php: -------------------------------------------------------------------------------- 1 | collection = new \Ufee\Amo\Base\Collections\Collection($elements); 18 | $this->collection->each(function(&$item) use($account) { 19 | $item = new Pipeline($item, $account); 20 | }); 21 | $this->attributes['account'] = $account; 22 | } 23 | 24 | /** 25 | * Get pipeline from id 26 | * @param $id - pipeline id 27 | * @return Pipeline 28 | */ 29 | public function byId($id) 30 | { 31 | return $this->collection->find('id', $id)->first(); 32 | } 33 | 34 | /** 35 | * Get main pipeline 36 | * @return Pipeline 37 | */ 38 | public function main() 39 | { 40 | return $this->collection->find('is_main', 1)->first(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Collections/PipelineStatusesCollection.php: -------------------------------------------------------------------------------- 1 | collection = new \Ufee\Amo\Base\Collections\Collection($elements); 19 | $this->collection->each(function(&$item) use ($pipeline) { 20 | $item = new PipelineStatus($item, $pipeline); 21 | }); 22 | } 23 | 24 | /** 25 | * Get status from id 26 | * @param $id - status id 27 | * @return PipelineStatus 28 | */ 29 | public function byId($id) 30 | { 31 | return $this->collection->find('id', $id)->first(); 32 | } 33 | 34 | /** 35 | * Get status success (142) 36 | * @return PipelineStatus 37 | */ 38 | public function success() 39 | { 40 | return $this->collection->find('id', 142)->first(); 41 | } 42 | 43 | /** 44 | * Get status loss (143) 45 | * @return PipelineStatus 46 | */ 47 | public function loss() 48 | { 49 | return $this->collection->find('id', 143)->first(); 50 | } 51 | 52 | /** 53 | * Get closed statuses 54 | * @return Collection 55 | */ 56 | public function closed() 57 | { 58 | $closed = $this->collection->find(function($status) { 59 | return in_array($status->id, [142, 143]); 60 | }); 61 | return $closed; 62 | } 63 | 64 | /** 65 | * Get opened statuses 66 | * @return Collection 67 | */ 68 | public function opened() 69 | { 70 | $opened = $this->collection->find(function($status) { 71 | return !in_array($status->id, [142, 143]); 72 | }); 73 | return $opened; 74 | } 75 | 76 | /** 77 | * Get closed statuses 78 | * @return Collection 79 | */ 80 | public function last() 81 | { 82 | return $this->closed(); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Collections/ServiceCollection.php: -------------------------------------------------------------------------------- 1 | collection = new \Ufee\Amo\Base\Collections\Collection($elements); 17 | $this->attributes['service'] = $service; 18 | } 19 | 20 | public function service() 21 | { 22 | return $this->attributes['service']; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Collections/TaskCollection.php: -------------------------------------------------------------------------------- 1 | collection = new \Ufee\Amo\Base\Collections\Collection($elements); 17 | $this->attributes['account'] = $account; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Collections/TransactionsCollection.php: -------------------------------------------------------------------------------- 1 | service->delete( 15 | $this->all() 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Collections/UserCollection.php: -------------------------------------------------------------------------------- 1 | find('id', $id)->first(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Collections/UserGroupCollection.php: -------------------------------------------------------------------------------- 1 | find('id', $id)->first()) { 18 | $group = new UserGroup([ 19 | 'id' => '', 20 | 'name' => '', 21 | 'client_id' => '' 22 | ]); 23 | } 24 | return $group; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Collections/WebhookCollection.php: -------------------------------------------------------------------------------- 1 | response->parseJson()) { 21 | throw new \Exception('Invalid API response (non JSON), code: '.$query->response->getCode()); 22 | } 23 | if (isset($data->response) && isset($data->response->error) && isset($data->response->error_code)) { 24 | throw new \Exception('API Error: '.$data->response->error_code.' - '.$data->response->error.', http code: '.$query->response->getCode()); 25 | } 26 | if (!isset($data->id)) { 27 | throw new \Exception('Invalid API response (account: not found), code: '.$query->response->getCode()); 28 | } 29 | return new \Ufee\Amo\Models\Account($data, $this->service); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Methods/CatalogElements/CatalogElementsAdd.php: -------------------------------------------------------------------------------- 1 | call(['add' => $raws], $arg); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Methods/CatalogElements/CatalogElementsDelete.php: -------------------------------------------------------------------------------- 1 | call(['delete' => $ids], $arg); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Methods/CatalogElements/CatalogElementsList.php: -------------------------------------------------------------------------------- 1 | call(['update' => $raws], $arg); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Methods/Catalogs/CatalogsAdd.php: -------------------------------------------------------------------------------- 1 | call(['add' => $raws], $arg); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Methods/Catalogs/CatalogsDelete.php: -------------------------------------------------------------------------------- 1 | call(['delete' => $ids], $arg); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Methods/Catalogs/CatalogsList.php: -------------------------------------------------------------------------------- 1 | call(['update' => $raws], $arg); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Methods/Companies/CompaniesAdd.php: -------------------------------------------------------------------------------- 1 | call(['add' => $raws], $arg); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Methods/Companies/CompaniesList.php: -------------------------------------------------------------------------------- 1 | call(['update' => $raws], $arg); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Methods/Contacts/ContactsAdd.php: -------------------------------------------------------------------------------- 1 | call(['add' => $raws], $arg); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Methods/Contacts/ContactsList.php: -------------------------------------------------------------------------------- 1 | call(['update' => $raws], $arg); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Methods/Customers/CustomersAdd.php: -------------------------------------------------------------------------------- 1 | call(['add' => $raws], $arg); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Methods/Customers/CustomersDelete.php: -------------------------------------------------------------------------------- 1 | call(['delete' => $ids], $arg); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Methods/Customers/CustomersList.php: -------------------------------------------------------------------------------- 1 | call(['update' => $raws], $arg); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Methods/Leads/LeadsAdd.php: -------------------------------------------------------------------------------- 1 | call(['add' => $raws], $arg); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Methods/Leads/LeadsList.php: -------------------------------------------------------------------------------- 1 | call(['update' => $raws], $arg); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Methods/Notes/NotesAdd.php: -------------------------------------------------------------------------------- 1 | call(['add' => $raws], $arg); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Methods/Notes/NotesList.php: -------------------------------------------------------------------------------- 1 | call(['update' => $raws], $arg); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Methods/Tasks/TasksAdd.php: -------------------------------------------------------------------------------- 1 | call(['add' => $raws], $arg); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Methods/Tasks/TasksList.php: -------------------------------------------------------------------------------- 1 | call(['update' => $raws], $arg); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Methods/Transactions/TransactionsAdd.php: -------------------------------------------------------------------------------- 1 | call(['add' => $raws], $arg); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Methods/Transactions/TransactionsDelete.php: -------------------------------------------------------------------------------- 1 | call(['delete' => $ids], $arg); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Methods/Transactions/TransactionsList.php: -------------------------------------------------------------------------------- 1 | call(['update' => $raws], $arg); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Methods/Webhooks/WebhooksList.php: -------------------------------------------------------------------------------- 1 | url = '/api/v2/webhooks/subscribe'; 20 | 21 | $result = $this->call(['subscribe' => $raws], $arg); 22 | $result->each(function($hook) { 23 | if (!$hook->result) { 24 | if (isset($hook->notice)) { 25 | throw new \Exception('Error subscribe hook: '.$hook->notice); 26 | } 27 | throw new \Exception('Unknown error subscribe hook'); 28 | } 29 | }); 30 | return $result; 31 | } 32 | 33 | /** 34 | * Unubscribe hooks in CRM 35 | * @param array $raws 36 | * @param array $arg 37 | * @return 38 | */ 39 | public function unsubscribe($raws, $arg = []) 40 | { 41 | $this->url = '/api/v2/webhooks/unsubscribe'; 42 | 43 | $result = $this->call(['unsubscribe' => $raws], $arg); 44 | $result->each(function($hook) { 45 | if (!$hook->result) { 46 | if (isset($hook->notice)) { 47 | throw new \Exception('Error unsubscribe hook: '.$hook->notice); 48 | } 49 | throw new \Exception('Unknown error unsubscribe hook'); 50 | } 51 | }); 52 | return $result; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Models/Account.php: -------------------------------------------------------------------------------- 1 | system as $field_key) { 40 | $this->attributes[$field_key] = null; 41 | } 42 | foreach ($this->hidden as $field_key) { 43 | $this->attributes[$field_key] = null; 44 | } 45 | foreach ($this->writable as $field_key) { 46 | $this->attributes[$field_key] = null; 47 | } 48 | foreach ($data as $field_key=>$val) { 49 | if (array_key_exists($field_key, $this->attributes)) { 50 | $this->attributes[$field_key] = $val; 51 | } 52 | } 53 | $this->attributes['service'] = $service; 54 | $this->_boot($data); 55 | } 56 | 57 | /** 58 | * Model on load 59 | * @param array $data 60 | * @return void 61 | */ 62 | protected function _boot($data = []) 63 | { 64 | $client_id = $this->service->instance->getAuth('id'); 65 | // группы пользователей 66 | $groups = [ 67 | new \Ufee\Amo\Models\UserGroup(['id' => 0, 'name' => 'Отдел продаж', 'client_id' => $client_id]) 68 | ]; 69 | foreach ($data->_embedded->groups as $id=>$group) { 70 | $group->client_id = $client_id; 71 | $groups[$id]= new \Ufee\Amo\Models\UserGroup($group); 72 | } 73 | $this->attributes['userGroups'] = new Collections\UserGroupCollection($groups); 74 | // пользователи 75 | $users = []; 76 | foreach ($data->_embedded->users as $id=>$user) { 77 | $users[$id]= new \Ufee\Amo\Models\User($user, $this->userGroups->byId($user->group_id)); 78 | } 79 | $this->attributes['users'] = new Collections\UserCollection($users); 80 | $this->attributes['currentUser'] = $this->attributes['users']->get($data->current_user); 81 | 82 | // воронки 83 | $this->attributes['pipelines'] = new Collections\PipelineCollection( 84 | (array)$data->_embedded->pipelines, $this 85 | ); 86 | // типы примечаний 87 | $this->attributes['noteTypes'] = new Collections\NoteTypesCollection( 88 | (array)$data->_embedded->note_types, $this 89 | ); 90 | // типы задач 91 | $this->attributes['taskTypes'] = new Collections\TaskTypesCollection( 92 | (array)$data->_embedded->task_types, $this 93 | ); 94 | $catalogCustomFields = []; 95 | if (isset($data->_embedded->custom_fields->catalogs)) { 96 | foreach ($data->_embedded->custom_fields->catalogs as $catalog_id=>$cfields) { 97 | $catalogCustomFields[$catalog_id] = (array)$cfields; 98 | } 99 | } 100 | // дополнительные поля 101 | $this->attributes['customFields'] = new AccountCustomFields( 102 | (array)$data->_embedded->custom_fields->companies, 103 | (array)$data->_embedded->custom_fields->contacts, 104 | (array)$data->_embedded->custom_fields->leads, 105 | (array)$data->_embedded->custom_fields->customers, 106 | $catalogCustomFields, 107 | $this 108 | ); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/Models/AccountCustomFields.php: -------------------------------------------------------------------------------- 1 | attributes['companies'] = new Collections\CompaniesCustomFieldCollection($cf_company_elems, $account); 26 | $this->attributes['contacts'] = new Collections\ContactsCustomFieldCollection($cf_contacts_elems, $account); 27 | $this->attributes['leads'] = new Collections\LeadsCustomFieldCollection($cf_leads_elems, $account); 28 | $this->attributes['customers'] = new Collections\CustomersCustomFieldCollection($cf_customers_elems, $account); 29 | $catalogFields = []; 30 | foreach ($cf_catalogs as $catalog_id=>$cf_from_catalog) { 31 | $catalogFields[$catalog_id] = new Collections\CatalogCustomFieldCollection($cf_from_catalog, $account); 32 | } 33 | $this->attributes['catalogs'] = new Collection($catalogFields); 34 | $this->attributes['account'] = $account; 35 | } 36 | 37 | /** 38 | * Protect get fields 39 | * @param string $field 40 | */ 41 | public function __get($field) 42 | { 43 | if (!array_key_exists($field, $this->attributes)) { 44 | throw new \Exception('Invalid '.static::class.' attribute: '.$field); 45 | } 46 | return $this->attributes[$field]; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Models/Catalog.php: -------------------------------------------------------------------------------- 1 | service->delete($this); 39 | } 40 | 41 | /** 42 | * Convert Model to array 43 | * @return array 44 | */ 45 | public function toArray() 46 | { 47 | $fields = parent::toArray(); 48 | $fields['sort'] = $this->attributes['sort']; 49 | $fields['sdk_widget_code'] = $this->attributes['sdk_widget_code']; 50 | return $fields; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Models/CatalogElement.php: -------------------------------------------------------------------------------- 1 | attributes['leads_id'] = []; 49 | if (isset($data->leads->id)) { 50 | $this->attributes['leads_id'] = $data->leads->id; 51 | } 52 | $this->attributes['leads'] = null; 53 | unset( 54 | $this->attributes['customers']->_links 55 | ); 56 | } 57 | 58 | /** 59 | * Protect customFields access 60 | * @param mixed $customFields attribute 61 | * @return EntityCustomFields 62 | */ 63 | protected function customFields_access($customFields) 64 | { 65 | if (is_null($this->attributes['customFields'])) { 66 | 67 | $model_cfields = new Collection([]); 68 | $account_cfields = $this->service->account->customFields->{static::$cf_category}; 69 | $curr_custom_fields = $this->custom_fields; 70 | 71 | if (!$catalogFields = $account_cfields->get($this->catalog_id)) { 72 | throw new \Exception('Error init custom fields from catalog: '.$this->catalog_id); 73 | } 74 | foreach ($catalogFields->all() as $cfield) { 75 | $cf_data = [ 76 | 'id' => $cfield->id, 77 | 'account_id' => $this->service->account->id, 78 | 'name' => $cfield->name, 79 | 'code' => $cfield->code, 80 | 'values' => isset($curr_custom_fields[$cfield->id]) ? $curr_custom_fields[$cfield->id]->values : [], 81 | 'field' => $cfield 82 | ]; 83 | $cf_class = $catalogFields->getClassFrom($cfield); 84 | $model_cfields->push(new $cf_class($cf_data)); 85 | } 86 | $this->attributes['customFields'] = new EntityCustomFields($model_cfields); 87 | } 88 | return $this->attributes['customFields']; 89 | } 90 | 91 | /** 92 | * Protect catalog access 93 | * @param mixed $catalog attribute 94 | * @return Catalog 95 | */ 96 | public function catalog_access($catalog) 97 | { 98 | if (is_null($this->attributes['catalog'])) { 99 | $this->attributes['catalog'] = $this->service->instance->catalogs()->find($this->catalog_id); 100 | } 101 | return $this->attributes['catalog']; 102 | } 103 | 104 | /** 105 | * Delete model 106 | * @return array 107 | */ 108 | public function delete() 109 | { 110 | return $this->service->delete($this); 111 | } 112 | 113 | /** 114 | * Convert Model to array 115 | * @return array 116 | */ 117 | public function toArray() 118 | { 119 | $fields = parent::toArray(); 120 | return $fields; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/Models/Company.php: -------------------------------------------------------------------------------- 1 | attributes['tags'] = []; 54 | if (isset($data->tags)) { 55 | foreach ($data->tags as $tag) { 56 | $this->attributes['tags'][]= $tag->name; 57 | } 58 | } 59 | $this->attributes['leads_id'] = []; 60 | if (isset($data->leads->id)) { 61 | $this->attributes['leads_id'] = $data->leads->id; 62 | } 63 | $this->attributes['leads'] = null; 64 | 65 | $this->attributes['contacts_id'] = []; 66 | if (isset($data->contacts->id)) { 67 | $this->attributes['contacts_id'] = $data->contacts->id; 68 | } 69 | $this->attributes['contacts'] = null; 70 | 71 | $this->attributes['customers_id'] = []; 72 | if (isset($data->customers->id)) { 73 | $this->attributes['customers_id'] = $data->customers->id; 74 | } 75 | $this->attributes['customers'] = null; 76 | } 77 | 78 | /** 79 | * Create linked lead model 80 | * @return Lead 81 | */ 82 | public function createLead() 83 | { 84 | $company = $this; 85 | $lead = $this->service->instance->leads()->create(); 86 | $lead->responsible_user_id = $this->responsible_user_id; 87 | $lead->attachCompany($this); 88 | 89 | $lead->onCreate(function(&$model) use (&$company) { 90 | $company->attachLead($model); 91 | }); 92 | return $lead; 93 | } 94 | 95 | /** 96 | * Create linked contact model 97 | * @return Contact 98 | */ 99 | public function createContact() 100 | { 101 | $company = $this; 102 | $contact = $this->service->instance->contacts()->create(); 103 | $contact->responsible_user_id = $this->responsible_user_id; 104 | $contact->attachCompany($this); 105 | 106 | $contact->onCreate(function(&$model) use (&$company) { 107 | $company->attachContact($model); 108 | }); 109 | return $contact; 110 | } 111 | 112 | /** 113 | * Create linked customer model 114 | * @return Customer 115 | */ 116 | public function createCustomer() 117 | { 118 | $company = $this; 119 | $customer = $this->service->instance->customers()->create(); 120 | $customer->responsible_user_id = $this->responsible_user_id; 121 | $customer->attachCompany($this); 122 | 123 | $customer->onCreate(function(&$model) use (&$company) { 124 | $company->attachCustomer($model); 125 | }); 126 | return $customer; 127 | } 128 | 129 | /** 130 | * Convert Model to array 131 | * @return array 132 | */ 133 | public function toArray() 134 | { 135 | $fields = parent::toArray(); 136 | $fields['tags'] = $this->attributes['tags']; 137 | return $fields; 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/Models/Contact.php: -------------------------------------------------------------------------------- 1 | attributes['tags'] = []; 57 | if (isset($data->tags)) { 58 | foreach ($data->tags as $tag) { 59 | $this->attributes['tags'][]= $tag->name; 60 | } 61 | } 62 | $this->attributes['company_id'] = null; 63 | if (isset($data->company->id)) { 64 | $this->attributes['company_id'] = $data->company->id; 65 | $this->attributes['company_name'] = $data->company->name; 66 | } 67 | $this->attributes['company'] = null; 68 | 69 | $this->attributes['leads_id'] = []; 70 | if (isset($data->leads->id)) { 71 | $this->attributes['leads_id'] = $data->leads->id; 72 | } 73 | $this->attributes['leads'] = null; 74 | 75 | $this->attributes['customers_id'] = []; 76 | if (isset($data->customers->id)) { 77 | $this->attributes['customers_id'] = $data->customers->id; 78 | } 79 | $this->attributes['customers'] = null; 80 | } 81 | 82 | /** 83 | * Create linked lead model 84 | * @return Lead 85 | */ 86 | public function createLead() 87 | { 88 | $contact = $this; 89 | $lead = $this->service->instance->leads()->create(); 90 | $lead->responsible_user_id = $this->responsible_user_id; 91 | $lead->attachContact($this); 92 | 93 | if ($this->hasCompany()) { 94 | $lead->attachCompany($this->company_id); 95 | } 96 | $lead->onCreate(function(&$model) use (&$contact) { 97 | $contact->attachLead($model); 98 | }); 99 | return $lead; 100 | } 101 | 102 | /** 103 | * Create linked company model 104 | * @return Company 105 | */ 106 | public function createCompany() 107 | { 108 | $contact = $this; 109 | $company = $this->service->instance->companies()->create(); 110 | $company->responsible_user_id = $this->responsible_user_id; 111 | $company->attachContact($this); 112 | 113 | $company->onCreate(function(&$model) use (&$contact) { 114 | $contact->attachCompany($model); 115 | }); 116 | return $company; 117 | } 118 | 119 | /** 120 | * Create linked customer model 121 | * @return Customer 122 | */ 123 | public function createCustomer() 124 | { 125 | $contact = $this; 126 | $customer = $this->service->instance->customers()->create(); 127 | $customer->responsible_user_id = $this->responsible_user_id; 128 | $customer->attachContact($this); 129 | 130 | $customer->onCreate(function(&$model) use (&$contact) { 131 | $contact->attachCustomer($model); 132 | }); 133 | return $customer; 134 | } 135 | 136 | /** 137 | * Convert Model to array 138 | * @return array 139 | */ 140 | public function toArray() 141 | { 142 | $fields = parent::toArray(); 143 | $fields['tags'] = $this->attributes['tags']; 144 | return $fields; 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/Models/CustomField.php: -------------------------------------------------------------------------------- 1 | is_multiple; 33 | } 34 | 35 | /** 36 | * Is system field 37 | * @return bool 38 | */ 39 | public function isSystem() 40 | { 41 | return (bool)$this->is_system; 42 | } 43 | 44 | /** 45 | * Is editable field 46 | * @return bool 47 | */ 48 | public function isEditable() 49 | { 50 | return (bool)$this->is_editable; 51 | } 52 | 53 | /** 54 | * Get Amoapi instance 55 | * @return ApiClient 56 | */ 57 | public function instance() 58 | { 59 | $apiClass = is_numeric($this->client_id) ? Amoapi::class : Oauthapi::class; 60 | return $apiClass::getInstance($this->client_id); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Models/Customer.php: -------------------------------------------------------------------------------- 1 | attributes['tags'] = []; 62 | if (isset($data->tags)) { 63 | foreach ($data->tags as $tag) { 64 | $this->attributes['tags'][]= $tag->name; 65 | } 66 | } 67 | $this->attributes['company_id'] = null; 68 | if (isset($data->company->id)) { 69 | $this->attributes['company_id'] = $data->company->id; 70 | } 71 | $this->attributes['company'] = null; 72 | 73 | $this->attributes['contacts_id'] = []; 74 | if (isset($data->contacts->id)) { 75 | $this->attributes['contacts_id'] = $data->contacts->id; 76 | } 77 | $this->attributes['contacts'] = null; 78 | 79 | $this->attributes['main_contact_id'] = null; 80 | if (isset($data->main_contact->id)) { 81 | $this->attributes['main_contact_id'] = $data->main_contact->id; 82 | } 83 | unset( 84 | $this->attributes['main_contact'] 85 | ); 86 | } 87 | 88 | /** 89 | * Create linked transaction model 90 | * @return Transaction 91 | */ 92 | public function createTransaction() 93 | { 94 | $transaction = $this->service->instance->transactions()->create(); 95 | $transaction->attachCustomer($this); 96 | return $transaction; 97 | } 98 | 99 | /** 100 | * Linked transactions get method 101 | * @return TransactionsList 102 | */ 103 | public function transactions() 104 | { 105 | return $this->service->instance->transactions()->where('customer_id', $this->id); 106 | } 107 | 108 | /** 109 | * Protect transactions access 110 | * @param mixed $transactions attribute 111 | * @return TransactionsCollection 112 | */ 113 | public function transactions_access($transactions) 114 | { 115 | if (is_null($this->attributes['transactions'])) { 116 | $this->attributes['transactions'] = $this->service->instance->transactions()->where('customer_id', $this->id)->recursiveCall(); 117 | } 118 | return $this->attributes['transactions']; 119 | } 120 | 121 | /** 122 | * Delete model 123 | * @return array 124 | */ 125 | public function delete() 126 | { 127 | return $this->service->delete($this); 128 | } 129 | 130 | /** 131 | * Convert Model to array 132 | * @return array 133 | */ 134 | public function toArray() 135 | { 136 | $fields = parent::toArray(); 137 | return $fields; 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/Models/EntityCustomFields.php: -------------------------------------------------------------------------------- 1 | attributes['fields'] = $fields; 20 | } 21 | 22 | /** 23 | * Get cf by name 24 | * @param string $name 25 | * @return mixed 26 | */ 27 | public function byName($cf_name) 28 | { 29 | return $this->fields->find('name', $cf_name)->first(); 30 | } 31 | 32 | /** 33 | * Get cf by id 34 | * @param integer $cf_id 35 | * @return mixed 36 | */ 37 | public function byId($cf_id) 38 | { 39 | return $this->fields->find('id', $cf_id)->first(); 40 | } 41 | 42 | /** 43 | * Get cf by code 44 | * @param string $cf_code 45 | * @return mixed 46 | */ 47 | public function byCode($cf_code) 48 | { 49 | return $this->fields->find('code', $cf_code)->first(); 50 | } 51 | 52 | /** 53 | * Get cf by type id 54 | * @param string $cf_id 55 | * @return Collection 56 | */ 57 | public function byTypeId($cf_id) 58 | { 59 | return $this->fields->find('field_type', $cf_id); 60 | } 61 | 62 | /** 63 | * CF each 64 | * @param callable $callback 65 | */ 66 | public function each($callback) 67 | { 68 | return $this->fields->each($callback); 69 | } 70 | 71 | /** 72 | * Get cf changed in raw for api 73 | * @return array 74 | */ 75 | public function getChangedApiRaw() 76 | { 77 | $raw = []; 78 | $this->fields->each(function($cfield) use(&$raw) { 79 | if ($cfield->hasChanged('values')) { 80 | $raw[]= $cfield->getApiRaw(); 81 | } 82 | }); 83 | return $raw; 84 | } 85 | 86 | /** 87 | * Protect get fields 88 | * @param string $field 89 | */ 90 | public function __get($field) 91 | { 92 | if (!array_key_exists($field, $this->attributes)) { 93 | throw new \Exception('Invalid '.static::class.' attribute: '.$field); 94 | } 95 | return $this->attributes[$field]; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/Models/Note.php: -------------------------------------------------------------------------------- 1 | service->instance->ajax()->setNotePinned($this->id, $state); 56 | return true; 57 | } catch (\Exception $e) { 58 | return false; 59 | } 60 | } 61 | 62 | /** 63 | * Get attachment contents 64 | * return string 65 | */ 66 | public function getAttachment() 67 | { 68 | return $this->service->instance->ajax()->getAttachment($this->attachment); 69 | } 70 | 71 | /** 72 | * Convert Model to array 73 | * @return array 74 | */ 75 | public function toArray() 76 | { 77 | $fields = parent::toArray(); 78 | return $fields; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Models/Pipeline.php: -------------------------------------------------------------------------------- 1 | system as $field_key) { 33 | $this->attributes[$field_key] = null; 34 | } 35 | foreach ($this->hidden as $field_key) { 36 | $this->attributes[$field_key] = null; 37 | } 38 | foreach ($this->writable as $field_key) { 39 | $this->attributes[$field_key] = null; 40 | } 41 | foreach ($data as $field_key=>$val) { 42 | if (array_key_exists($field_key, $this->attributes)) { 43 | $this->attributes[$field_key] = $val; 44 | } 45 | } 46 | $this->attributes['account_id'] = $account->id; 47 | $this->attributes['statuses'] = new PipelineStatusesCollection( 48 | (array)$this->attributes['statuses'], $this 49 | ); 50 | } 51 | 52 | /** 53 | * Has main pipeline 54 | * @return bool 55 | */ 56 | public function hasMain() 57 | { 58 | return (bool)$this->is_main; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Models/Task.php: -------------------------------------------------------------------------------- 1 | result)) { 57 | $this->attributes['result']->entity = null; 58 | } 59 | unset( 60 | $this->attributes['result']->_links 61 | ); 62 | } 63 | 64 | /** 65 | * Get task expired status 66 | * @return bool 67 | */ 68 | public function hasExpired() 69 | { 70 | $date = new \DateTime('now', new \DateTimeZone($this->service->instance->getAuth('timezone'))); 71 | return !$this->is_completed && $date->format('Y-m-d H:i') > $this->endDate('Y-m-d H:i'); 72 | } 73 | 74 | /** 75 | * Get task start date 76 | * @return string 77 | */ 78 | public function startDate($format = 'Y-m-d H:i:s') 79 | { 80 | $date = new \DateTime(); 81 | $date->setTimestamp($this->complete_till_at); 82 | if (date('H:i', $this->complete_till_at) == '23:59') { 83 | $date->setTime(0,0,0); 84 | } 85 | $date->setTimezone(new \DateTimeZone($this->service->instance->getAuth('timezone'))); 86 | return $date->format($format); 87 | } 88 | 89 | /** 90 | * Get task end date 91 | * @return string 92 | */ 93 | public function endDate($format = 'Y-m-d H:i:s') 94 | { 95 | $date = new \DateTime(); 96 | $date->setTimestamp($this->complete_till_at+$this->duration); 97 | $date->setTimezone(new \DateTimeZone($this->service->instance->getAuth('timezone'))); 98 | return $date->format($format); 99 | } 100 | 101 | /** 102 | * Has linked result 103 | * @return bool 104 | */ 105 | public function hasResult() 106 | { 107 | return isset($this->attributes['result']->id); 108 | } 109 | 110 | /** 111 | * Get linked result 112 | * @param bool $force 113 | * @return Note|null 114 | */ 115 | public function getResult($force = false) 116 | { 117 | if (!isset($this->attributes['result']->id)) { 118 | return null; 119 | } 120 | if (is_null($this->attributes['result']->entity) || $force) { 121 | $this->attributes['result']->entity = $this->service->instance->notes()->where('type', 'task')->where('element_id', $this->attributes['result']->id)->call()->first(); 122 | } 123 | return $this->attributes['result']->entity; 124 | } 125 | 126 | /** 127 | * Convert Model to array 128 | * @return array 129 | */ 130 | public function toArray() 131 | { 132 | $fields = parent::toArray(); 133 | $fields['result_text'] = ''; 134 | if (isset($this->attributes['result']->id)) { 135 | $fields['result_text'] = $this->attributes['result']->text; 136 | } 137 | unset($fields['result']); 138 | return $fields; 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/Models/Transaction.php: -------------------------------------------------------------------------------- 1 | attributes['customer_id'] = null; 42 | if (isset($data->customer->id)) { 43 | $this->attributes['customer_id'] = $data->customer->id; 44 | } 45 | $this->attributes['customer'] = null; 46 | } 47 | 48 | /** 49 | * Set linked customer 50 | * @param mixed $customer 51 | * @return bool 52 | */ 53 | public function attachCustomer($customer) 54 | { 55 | if ($customer_id = $this->getIdFrom($customer)) { 56 | if ($customer instanceof \Ufee\Amo\Models\Customer) { 57 | $this->attributes['customer'] = $customer; 58 | } 59 | $this->customer_id = $customer_id; 60 | } 61 | return $this; 62 | } 63 | 64 | /** 65 | * Protect customer access 66 | * @param mixed $customer attribute 67 | * @return Customer 68 | */ 69 | public function customer_access($customer) 70 | { 71 | if (is_null($this->attributes['customer'])) { 72 | $this->attributes['customer'] = $this->service->instance->customers()->find($this->customer_id); 73 | } 74 | return $this->attributes['customer']; 75 | } 76 | 77 | /** 78 | * Get changed raw model api data 79 | * @return array 80 | */ 81 | public function getChangedRawApiData() 82 | { 83 | $data = $this->getChangedData(); 84 | $data['transaction_id'] = $this->id; 85 | return $data; 86 | } 87 | 88 | /** 89 | * Delete model 90 | * @return array 91 | */ 92 | public function delete() 93 | { 94 | return $this->service->delete($this); 95 | } 96 | 97 | /** 98 | * Convert Model to array 99 | * @return array 100 | */ 101 | public function toArray() 102 | { 103 | $fields = parent::toArray(); 104 | return $fields; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/Models/User.php: -------------------------------------------------------------------------------- 1 | attributes['phone'] = $data->phone_number; 40 | $this->attributes['group'] = $group; 41 | } 42 | 43 | /** 44 | * Get user activity 45 | * @param string $from - date start d.m.Y 46 | * @param string|null $to - date end d.m.Y 47 | * @return object 48 | */ 49 | public function getActivity($from, $to = null) 50 | { 51 | if (is_null($to)) { 52 | $to = $from; 53 | } 54 | $key = $from.'.'.$to; 55 | if (!isset($this->_activity[$key])) { 56 | $result = $this->group->instance()->ajax()->get('/ajax/stats/by_activities/'.$this->id.'/', [ 57 | 'from' => $from, 58 | 'to' => $to 59 | ]); 60 | if (is_object($result) && property_exists($result, 'response')) { 61 | $result->response->tasks->total_size = $result->response->tasks_count; 62 | $this->_activity[$key] = (object)[ 63 | 'leads' => $result->response->leads, 64 | 'contacts' => $result->response->contacts, 65 | 'tasks' => $result->response->tasks, 66 | 'notes' => $result->response->notes, 67 | 'customers' => $result->response->customers 68 | ]; 69 | $result = null; 70 | } 71 | } 72 | return $this->_activity[$key]; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Models/UserGroup.php: -------------------------------------------------------------------------------- 1 | client_id)) { 25 | return Amoapi::getInstance($this->client_id); 26 | } 27 | return Oauthapi::getInstance($this->client_id); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Models/Webhook.php: -------------------------------------------------------------------------------- 1 | id = $this->instance->getAuth('id'); 25 | $this->domain = $this->instance->getAuth('domain'); 26 | $this->api_args = [ 27 | 'with' => 'users,groups,pipelines,custom_fields,note_types,task_types', 28 | //'lang' => $this->instance->getAuth('lang') 29 | ]; 30 | } 31 | 32 | /** 33 | * Get with arguments 34 | * @param mixed 35 | */ 36 | public function with() 37 | { 38 | $values = func_get_args(); 39 | if (count($values) == 1) { 40 | $values = $values[0]; 41 | } 42 | return $this->current->call([ 43 | 'with' => join(',', $values) 44 | ]); 45 | } 46 | 47 | /** 48 | * Get full 49 | * @return Account 50 | */ 51 | public function account() 52 | { 53 | $key = $this->domain.$this->id; 54 | if (!array_key_exists($key, static::$_current_data)) { 55 | static::$_current_data[$key] = $this->current->call(); 56 | } 57 | return static::$_current_data[$key]; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Services/CatalogElements.php: -------------------------------------------------------------------------------- 1 | ['catalog_id', 'name'], 16 | 'update' => ['id', 'name', 'catalog_id', 'updated_at'] 17 | ]; 18 | protected 19 | $entity_key = 'catalog_elements', 20 | $entity_model = '\Ufee\Amo\Models\CatalogElement', 21 | $entity_collection = '\Ufee\Amo\Collections\CatalogElementCollection', 22 | $cache_time = false, 23 | $methods = [ 24 | 'list', 'add', 'update', 'delete' 25 | ]; 26 | 27 | /** 28 | * Get full 29 | * @return Collection 30 | */ 31 | public function catalogElements() 32 | { 33 | return $this->list->recursiveCall(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Services/Catalogs.php: -------------------------------------------------------------------------------- 1 | ['name'], 12 | 'update' => ['id'] 13 | ]; 14 | protected 15 | $entity_key = 'catalogs', 16 | $entity_model = '\Ufee\Amo\Models\Catalog', 17 | $entity_collection = '\Ufee\Amo\Collections\CatalogCollection', 18 | $cache_time = false, 19 | $methods = [ 20 | 'list', 'add', 'update', 'delete' 21 | ]; 22 | 23 | /** 24 | * Add catalogs to CRM 25 | * @param mixed $models 26 | */ 27 | public function add(&$models) 28 | { 29 | $create_models = $models; 30 | if (!is_array($models)) { 31 | $create_models = [$models]; 32 | } 33 | $added_raws = $this->_add($create_models); 34 | $added = true; 35 | foreach ($create_models as $k=>&$model) { 36 | if ($added_raw = $added_raws->get($k)) { 37 | $model->setId($added_raw->id); 38 | $model->setQueryHash($added_raw->query_hash); 39 | $model->saved(); 40 | } else { 41 | $added = false; 42 | } 43 | } 44 | if (!is_array($models)) { 45 | if (!isset($create_models[0])) { 46 | throw new \Exception('Error: empty created models'); 47 | } 48 | $models = $create_models[0]; 49 | } else { 50 | $models = $create_models; 51 | } 52 | return $added; 53 | } 54 | 55 | /** 56 | * Get full 57 | * @return Collection 58 | */ 59 | public function catalogs() 60 | { 61 | return $this->list->recursiveCall(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Services/Companies.php: -------------------------------------------------------------------------------- 1 | ['name'], 15 | 'update' => ['id', 'updated_at'] 16 | ]; 17 | protected 18 | $entity_key = 'companies', 19 | $entity_model = '\Ufee\Amo\Models\Company', 20 | $entity_collection = '\Ufee\Amo\Collections\CompanyCollection', 21 | $cache_time = false; 22 | 23 | /** 24 | * Get full 25 | * @return Collection 26 | */ 27 | public function companies() 28 | { 29 | return $this->list->recursiveCall(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Services/Contacts.php: -------------------------------------------------------------------------------- 1 | ['name'], 15 | 'update' => ['id', 'updated_at'] 16 | ]; 17 | protected 18 | $entity_key = 'contacts', 19 | $entity_model = '\Ufee\Amo\Models\Contact', 20 | $entity_collection = '\Ufee\Amo\Collections\ContactCollection', 21 | $cache_time = false; 22 | 23 | /** 24 | * Get full 25 | * @return Collection 26 | */ 27 | public function contacts() 28 | { 29 | return $this->list->recursiveCall(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Services/Customers.php: -------------------------------------------------------------------------------- 1 | ['name', 'next_date'], 12 | 'update' => ['id', 'updated_at'] 13 | ]; 14 | protected 15 | $entity_key = 'customers', 16 | $entity_model = '\Ufee\Amo\Models\Customer', 17 | $entity_collection = '\Ufee\Amo\Collections\CustomerCollection', 18 | $cache_time = false, 19 | $methods = [ 20 | 'list', 'add', 'update', 'delete' 21 | ]; 22 | 23 | /** 24 | * Get full 25 | * @return Collection 26 | */ 27 | public function customers() 28 | { 29 | return $this->list->recursiveCall(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Services/Leads.php: -------------------------------------------------------------------------------- 1 | ['name'], 15 | 'update' => ['id', 'updated_at'] 16 | ]; 17 | protected 18 | $entity_key = 'leads', 19 | $entity_model = '\Ufee\Amo\Models\Lead', 20 | $entity_collection = '\Ufee\Amo\Collections\LeadCollection', 21 | $cache_time = false; 22 | 23 | /** 24 | * Service on load 25 | * @return void 26 | */ 27 | protected function _boot() 28 | { 29 | parent::_boot(); 30 | $this->api_args['with'] = 'loss_reason_name,catalog_elements_links'; 31 | } 32 | 33 | /** 34 | * Get full 35 | * @return Collection 36 | */ 37 | public function leads() 38 | { 39 | return $this->list->recursiveCall(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Services/Notes.php: -------------------------------------------------------------------------------- 1 | ['element_id','element_type','note_type','text'], 12 | 'update' => ['id', 'updated_at'] 13 | ]; 14 | protected 15 | $entity_key = 'notes', 16 | $entity_model = '\Ufee\Amo\Models\Note', 17 | $entity_collection = '\Ufee\Amo\Collections\NoteCollection', 18 | $cache_time = false; 19 | 20 | /** 21 | * Get notes by type 22 | * @param integer $note_type 4,... 23 | * @param string $element_type - contact/lead/company/task 24 | * @return Collection 25 | */ 26 | public function type($note_type, $element_type = 'all') 27 | { 28 | return $this->list->where('note_type', $note_type) 29 | ->where('type', $element_type) 30 | ->recursiveCall(); 31 | } 32 | 33 | /** 34 | * Get full 35 | * @return Collection 36 | */ 37 | public function notes() 38 | { 39 | return $this->list->where('type', 'all') 40 | ->recursiveCall(); 41 | } 42 | 43 | /** 44 | * Get models by id 45 | * @param integer|array $id 46 | * @param string $element_type - contact/lead/company/task 47 | * @return Model|Collection 48 | */ 49 | public function find($id, $element_type = 'lead') 50 | { 51 | $result = $this->list->where('limit_rows', is_array($id) ? count($id) : 1) 52 | ->where('limit_offset', 0) 53 | ->where('type', $element_type) 54 | ->where('id', $id) 55 | ->call(); 56 | if (is_array($id)) { 57 | return $result; 58 | } 59 | if (!$model = $result->get(0)) { 60 | return null; 61 | } 62 | return $model; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Services/Tasks.php: -------------------------------------------------------------------------------- 1 | ['text'], 12 | 'update' => ['id', 'updated_at'] 13 | ]; 14 | protected 15 | $entity_key = 'tasks', 16 | $entity_model = '\Ufee\Amo\Models\Task', 17 | $entity_collection = '\Ufee\Amo\Collections\TaskCollection', 18 | $cache_time = false; 19 | 20 | /** 21 | * Get full 22 | * @return Collection 23 | */ 24 | public function tasks() 25 | { 26 | return $this->list->recursiveCall(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Services/Transactions.php: -------------------------------------------------------------------------------- 1 | ['customer_id', 'price'], 13 | 'update' => ['comment'] 14 | ]; 15 | protected 16 | $entity_key = 'transactions', 17 | $entity_model = '\Ufee\Amo\Models\Transaction', 18 | $entity_collection = '\Ufee\Amo\Collections\TransactionsCollection', 19 | $cache_time = false, 20 | $methods = [ 21 | 'list', 'add', 'update', 'delete' 22 | ]; 23 | 24 | /** 25 | * Add transactions to CRM 26 | * @param mixed $models 27 | */ 28 | public function add(&$models) 29 | { 30 | $create_models = $models; 31 | if (!is_array($models)) { 32 | $create_models = [$models]; 33 | } 34 | $create_parts = []; 35 | $p = 0; 36 | $i = 1; 37 | foreach ($create_models as $create_model) { 38 | $create_parts[$p][] = $create_model; 39 | if ($i == $this->limit_rows_add) { 40 | $i = 1; 41 | $p++; 42 | } else { 43 | $i++; 44 | } 45 | } 46 | $added_raws = new Collection(); 47 | foreach ($create_parts as $part) { 48 | $added_part = $this->_add($part); 49 | $added_raws->merge($added_part); 50 | } 51 | $added = true; 52 | foreach ($create_models as $k=>&$model) { 53 | if ($added_raw = $added_raws->get($k)) { 54 | $model->setId($added_raw->id); 55 | $model->setQueryHash($added_raw->query_hash); 56 | $model->saved(); 57 | } else { 58 | $added = false; 59 | } 60 | } 61 | if (!is_array($models)) { 62 | if (!isset($create_models[0])) { 63 | throw new \Exception('Error: empty created models'); 64 | } 65 | $models = $create_models[0]; 66 | } else { 67 | $models = $create_models; 68 | } 69 | return $added; 70 | } 71 | 72 | /** 73 | * Get full 74 | * @return TransactionCollection 75 | */ 76 | public function transactions() 77 | { 78 | return $this->list->recursiveCall(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Services/Webhooks.php: -------------------------------------------------------------------------------- 1 | api_args = [ 25 | //'lang' => $this->instance->getAuth('lang') 26 | ]; 27 | } 28 | 29 | /** 30 | * Subscribe hooks in CRM 31 | * @param string $url 32 | * @param array $events 33 | * return bool 34 | */ 35 | public function subscribe($url, $events) 36 | { 37 | if (!is_string($url) || strpos($url, 'http') === false) { 38 | throw new \Exception('Error or invalid, "url" is required in Webhook'); 39 | } 40 | if (!is_array($events) || empty($events)) { 41 | throw new \Exception('Error or invalid, "events" is required in Webhook'); 42 | } 43 | $raw = [ 44 | 'url' => $url, 45 | 'events' => $events 46 | ]; 47 | $created = $this->subscriber->subscribe([$raw]); 48 | return $created->first()->result; 49 | } 50 | 51 | /** 52 | * Unsubscribe hooks in CRM 53 | * @param string $url 54 | * @param array $events 55 | * return bool 56 | */ 57 | public function unsubscribe($url, $events) 58 | { 59 | $raw = []; 60 | if (is_string($url) && strpos($url, 'http') !== false) { 61 | $raw['url'] = $url; 62 | } 63 | if (is_array($events) && !empty($events)) { 64 | $raw['events'] = $events; 65 | } 66 | if (!isset($raw['url']) && !isset($raw['events'])) { 67 | throw new \Exception('Error or invalid, "url" or "events" is required in Webhook'); 68 | } 69 | $deleted_raws = $this->subscriber->unsubscribe([$raw]); 70 | return $deleted_raws->first()->result; 71 | } 72 | 73 | /** 74 | * Get full 75 | * @return Collection 76 | */ 77 | public function webhooks() 78 | { 79 | return $this->list->call(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /tests/Cases/AjaxTest.php: -------------------------------------------------------------------------------- 1 | 5 | */ 6 | namespace Tests\Cases; 7 | 8 | use PHPUnit\Framework\Assert; 9 | use Ufee\Amo\Services; 10 | 11 | require_once __DIR__ . '/../TestCase.php'; 12 | 13 | class AjaxTest extends \Tests\TestCase 14 | { 15 | public function testGetAjaxCompaniesService() 16 | { 17 | $model = $this->amo->companies()->create(); 18 | $result = $this->amo->ajax()->get('/ajax/contacts/list/', [ 19 | 'element_type' => 3 20 | ]); 21 | Assert::assertTrue( 22 | (isset($result->response) && is_array($result->response->items)) 23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/Cases/AmoapiTest.php: -------------------------------------------------------------------------------- 1 | 5 | */ 6 | namespace Tests\Cases; 7 | 8 | use PHPUnit\Framework\Assert; 9 | use Ufee\Amo\Services, 10 | Ufee\Amo\Models, 11 | Ufee\Amo\Collections; 12 | 13 | require_once __DIR__ . '/../TestCase.php'; 14 | 15 | class AmoapiTest extends \Tests\TestCase 16 | { 17 | public function testGetAccountService() 18 | { 19 | Assert::assertInstanceOf( 20 | Services\Account::class, $this->amo->account() 21 | ); 22 | } 23 | 24 | public function testGetAccountCurrentMoodel() 25 | { 26 | Assert::assertInstanceOf( 27 | Models\Account::class, $this->amo->account 28 | ); 29 | } 30 | 31 | public function testGetApiQueriesCollection() 32 | { 33 | Assert::assertInstanceOf( 34 | Collections\QueryCollection::class, $this->amo->queries 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/Cases/CatalogsTest.php: -------------------------------------------------------------------------------- 1 | 5 | */ 6 | namespace Tests\Cases; 7 | 8 | use PHPUnit\Framework\Assert; 9 | use Ufee\Amo\Services; 10 | 11 | require_once __DIR__ . '/../TestCase.php'; 12 | 13 | class CatalogsTest extends \Tests\TestCase 14 | { 15 | public function testGetCatalogsService() 16 | { 17 | Assert::assertInstanceOf( 18 | Services\Catalogs::class, $this->amo->catalogs() 19 | ); 20 | } 21 | 22 | public function testCatalogManage() 23 | { 24 | $model = $this->amo->catalogs()->create(); 25 | $model->name = 'Test CreateCatalog '.time(); 26 | $has_created = $model->save(); 27 | 28 | Assert::assertTrue( 29 | ($has_created && is_numeric($model->id)) 30 | ); 31 | 32 | $catalog_id = $model->id; 33 | $model->name = 'Test UpdateCatalog'; 34 | $model->save(); 35 | $catalog = $this->amo->catalogs()->find($catalog_id); 36 | 37 | Assert::assertTrue( 38 | ($catalog->name === $model->name) 39 | ); 40 | 41 | $element = $catalog->createElement(); 42 | $element->name = 'Test CreateElement'; 43 | $has_created = $element->save(); 44 | 45 | Assert::assertTrue( 46 | ($has_created && is_numeric($element->id)) 47 | ); 48 | 49 | $element_id = $element->id; 50 | $element->name = 'Test UpdateElement'; 51 | $element->save(); 52 | $catalogEelement = $this->amo->catalogElements()->find($element_id); 53 | 54 | Assert::assertTrue( 55 | ($catalogEelement->name === $element->name) 56 | ); 57 | 58 | $element->delete(); 59 | $catalogEelement = $this->amo->catalogElements()->find($element_id); 60 | 61 | Assert::assertTrue( 62 | ($catalogEelement === null) 63 | ); 64 | 65 | $model->delete(); 66 | $catalog = $this->amo->catalogs()->find($catalog_id); 67 | 68 | Assert::assertTrue( 69 | ($catalog === null) 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /tests/Cases/CompaniesTest.php: -------------------------------------------------------------------------------- 1 | 5 | */ 6 | namespace Tests\Cases; 7 | 8 | use PHPUnit\Framework\Assert; 9 | use Ufee\Amo\Services; 10 | 11 | require_once __DIR__ . '/../TestCase.php'; 12 | 13 | class CompaniesTest extends \Tests\TestCase 14 | { 15 | public function testGetCompaniesService() 16 | { 17 | Assert::assertInstanceOf( 18 | Services\Companies::class, $this->amo->companies() 19 | ); 20 | } 21 | 22 | public function testUpdateCompanyName() 23 | { 24 | $model = $this->amo->companies()->create(); 25 | $model->name = 'Test UpdateCompany '.time(); 26 | $has_created = $model->save(); 27 | 28 | Assert::assertTrue( 29 | ($has_created && is_numeric($model->id)) 30 | ); 31 | 32 | $model->name = 'Test UpdateCompany NEW'; 33 | $model->save(); 34 | $model = $this->amo->companies()->find($model->id); 35 | 36 | Assert::assertEquals( 37 | $model->name, 'Test UpdateCompany NEW' 38 | ); 39 | } 40 | 41 | public function testCreateTwoCompanies() 42 | { 43 | $create_models = [ 44 | $this->amo->companies()->create(), 45 | $this->amo->companies()->create() 46 | ]; 47 | $create_models[0]->name = 'Test CreateTwoCompanies 1 '.time(); 48 | $create_models[1]->name = 'Test CreateTwoCompanies 2 '.time(); 49 | $has_created = $this->amo->companies()->add($create_models); 50 | 51 | Assert::assertTrue( 52 | ($has_created && is_numeric($create_models[0]->id) && is_numeric($create_models[1]->id)) 53 | ); 54 | } 55 | 56 | public function testSearchCompanyByEmail() 57 | { 58 | $cf_email = 'Email'; 59 | $time = time(); 60 | $email_set_val = 'test'.$time.'@test.ru'; 61 | $email_search_val = 'TEST'.$time.'@Test.Ru'; 62 | 63 | $model = $this->amo->companies()->create(); 64 | $model->name = 'Test SearchCompany '.$time; 65 | $model->cf($cf_email)->setValue($email_set_val); 66 | $has_created = $model->save(); 67 | 68 | Assert::assertTrue( 69 | ($has_created && is_numeric($model->id)) 70 | ); 71 | $companies = $this->amo->companies()->searchByEmail($email_search_val); 72 | 73 | Assert::assertTrue( 74 | ($companies->count() > 0 && $companies->first()->id == $model->id) 75 | ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /tests/Cases/ContactsTest.php: -------------------------------------------------------------------------------- 1 | 5 | */ 6 | namespace Tests\Cases; 7 | 8 | use PHPUnit\Framework\Assert; 9 | use Ufee\Amo\Services; 10 | 11 | require_once __DIR__ . '/../TestCase.php'; 12 | 13 | class ContactsTest extends \Tests\TestCase 14 | { 15 | public function testGetContactsService() 16 | { 17 | Assert::assertInstanceOf( 18 | Services\Contacts::class, $this->amo->contacts() 19 | ); 20 | } 21 | 22 | public function testUpdateContactName() 23 | { 24 | $model = $this->amo->contacts()->create(); 25 | $model->name = 'Test UpdateContact '.time(); 26 | $email = 'amoapitest'.time().'@amo.api'; 27 | $model->cf('Email')->setValue($email); 28 | $has_created = $model->save(); 29 | 30 | Assert::assertTrue( 31 | ($has_created && is_numeric($model->id)) 32 | ); 33 | 34 | $model->name = 'Test UpdateContact NEW'; 35 | $model->save(); 36 | $model = $this->amo->contacts()->find($model->id); 37 | 38 | Assert::assertEquals( 39 | $model->name, 'Test UpdateContact NEW' 40 | ); 41 | Assert::assertEquals( 42 | $model->cf('Email')->getValue(), $email 43 | ); 44 | } 45 | 46 | public function testCreateTwoContacts() 47 | { 48 | $create_models = [ 49 | $this->amo->contacts()->create(), 50 | $this->amo->contacts()->create() 51 | ]; 52 | $create_models[0]->name = 'Test CreateTwoContacts 1 '.time(); 53 | $create_models[1]->name = 'Test CreateTwoContacts 2 '.time(); 54 | $has_created = $this->amo->contacts()->add($create_models); 55 | 56 | Assert::assertTrue( 57 | ($has_created && is_numeric($create_models[0]->id) && is_numeric($create_models[1]->id)) 58 | ); 59 | } 60 | 61 | public function testSearchContactByPhone() 62 | { 63 | $cf_phone = $this->amo->getAuth('lang') == 'ru' ? 'Телефон' : 'Phone'; 64 | $time = time(); 65 | $phone_set_val = '+7'.$time; 66 | $phone_search_val = '8'.$time; 67 | 68 | $model = $this->amo->contacts()->create(); 69 | $model->name = 'Test SearchContact '.$time; 70 | $model->cf($cf_phone)->setValue($phone_set_val); 71 | $has_created = $model->save(); 72 | 73 | Assert::assertTrue( 74 | ($has_created && is_numeric($model->id)) 75 | ); 76 | $contacts = $this->amo->contacts()->searchByPhone($phone_search_val); 77 | 78 | Assert::assertTrue( 79 | ($contacts->count() > 0 && $contacts->first()->id == $model->id) 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /tests/Cases/CustomersTest.php: -------------------------------------------------------------------------------- 1 | 5 | */ 6 | namespace Tests\Cases; 7 | 8 | use PHPUnit\Framework\Assert; 9 | use Ufee\Amo\Services; 10 | 11 | require_once __DIR__ . '/../TestCase.php'; 12 | 13 | class CustomersTest extends \Tests\TestCase 14 | { 15 | public function testGetCustomersService() 16 | { 17 | Assert::assertInstanceOf( 18 | Services\Customers::class, $this->amo->customers() 19 | ); 20 | } 21 | 22 | public function testCustomersManage() 23 | { 24 | $model = $this->amo->customers()->create(); 25 | $model->name = 'Test CreateCustomer '.time(); 26 | $model->next_date = time(); 27 | $model->next_price = 100; 28 | $has_created = $model->save(); 29 | 30 | Assert::assertTrue( 31 | ($has_created && is_numeric($model->id)) 32 | ); 33 | 34 | $customer_id = $model->id; 35 | $model->name = 'Test UpdateCustomer'; 36 | $model->save(); 37 | $customer = $this->amo->customers()->find($customer_id); 38 | 39 | Assert::assertTrue( 40 | ($customer->name === $model->name) 41 | ); 42 | 43 | $transaction = $customer->createTransaction(); 44 | $transaction->price = 200; 45 | $has_created = $transaction->save(); 46 | 47 | Assert::assertTrue( 48 | ($has_created && is_numeric($transaction->id)) 49 | ); 50 | 51 | $transaction_id = $transaction->id; 52 | $transaction->comment = 'test'; 53 | $transaction->save(); 54 | $customerTransaction = $this->amo->transactions()->find($transaction_id); 55 | 56 | Assert::assertTrue( 57 | ($customerTransaction->comment === $transaction->comment) 58 | ); 59 | 60 | $transaction->delete(); 61 | $customerTransaction = $this->amo->transactions()->find($transaction_id); 62 | 63 | Assert::assertTrue( 64 | ($customerTransaction === null) 65 | ); 66 | 67 | $model->delete(); 68 | $customer = $this->amo->customers()->find($customer_id); 69 | 70 | Assert::assertTrue( 71 | ($customer === null) 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /tests/Cases/LeadsTest.php: -------------------------------------------------------------------------------- 1 | 5 | */ 6 | namespace Tests\Cases; 7 | 8 | use PHPUnit\Framework\Assert; 9 | use Ufee\Amo\Services; 10 | 11 | require_once __DIR__ . '/../TestCase.php'; 12 | 13 | class LeadsTest extends \Tests\TestCase 14 | { 15 | public function testGetLeadsService() 16 | { 17 | Assert::assertInstanceOf( 18 | Services\Leads::class, $this->amo->leads() 19 | ); 20 | } 21 | 22 | public function testUpdateLeadSale() 23 | { 24 | $model = $this->amo->leads()->create(); 25 | $model->name = 'Test UpdateLeadSale '.time(); 26 | $has_created = $model->save(); 27 | 28 | Assert::assertTrue( 29 | ($has_created && is_numeric($model->id)) 30 | ); 31 | 32 | $model->sale = 123000; 33 | $model->save(); 34 | $model = $this->amo->leads()->find($model->id); 35 | 36 | Assert::assertEquals( 37 | $model->sale, 123000 38 | ); 39 | } 40 | 41 | public function testCreateTwoLeads() 42 | { 43 | $create_models = [ 44 | $this->amo->leads()->create(), 45 | $this->amo->leads()->create() 46 | ]; 47 | $create_models[0]->name = 'Test CreateTwoLeads 1 '.time(); 48 | $create_models[1]->name = 'Test CreateTwoLeads 2 '.time(); 49 | $has_created = $this->amo->leads()->add($create_models); 50 | 51 | Assert::assertTrue( 52 | ($has_created && is_numeric($create_models[0]->id) && is_numeric($create_models[1]->id)) 53 | ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/Cases/LinkedNotesTest.php: -------------------------------------------------------------------------------- 1 | 5 | */ 6 | namespace Tests\Cases; 7 | 8 | use PHPUnit\Framework\Assert; 9 | use Ufee\Amo\Services; 10 | 11 | require_once __DIR__ . '/../TestCase.php'; 12 | 13 | class LinkedNotesTest extends \Tests\TestCase 14 | { 15 | public function testGetNotesService() 16 | { 17 | Assert::assertInstanceOf( 18 | Services\Notes::class, $this->amo->notes() 19 | ); 20 | } 21 | 22 | public function testUpdateLeadNote() 23 | { 24 | $lead = $this->amo->leads()->create(); 25 | $lead->name = 'Test UpdateLeadNote '.time(); 26 | $lead->save(); 27 | 28 | $note = $lead->createNote(4); 29 | $note->text = 'Test UpdateLeadNote '.time(); 30 | $note->element_type = 2; 31 | $note->element_id = $lead->id; 32 | $has_created = $note->save(); 33 | 34 | Assert::assertTrue( 35 | ($has_created && is_numeric($note->id)) 36 | ); 37 | 38 | $note->text = 'Test UpdateLeadNote NEW'; 39 | $note->save(); 40 | $note = $this->amo->notes()->find($note->id); 41 | 42 | Assert::assertEquals( 43 | $note->text, 'Test UpdateLeadNote NEW' 44 | ); 45 | } 46 | 47 | public function testCreateTwoLeadNotes() 48 | { 49 | $lead = $this->amo->leads()->create(); 50 | $lead->name = 'Test CreateTwoLeadNotes '.time(); 51 | $lead->save(); 52 | 53 | $create_notes = [ 54 | $lead->createNote(4), 55 | $lead->createNote(4) 56 | ]; 57 | $create_notes[0]->text = 'Test CreateTwoLeadNotes 1 '.time(); 58 | $create_notes[1]->text = 'Test CreateTwoLeadNotes 2 '.time(); 59 | $has_created = $this->amo->notes()->add($create_notes); 60 | 61 | Assert::assertTrue( 62 | ($has_created && is_numeric($create_notes[0]->id) && is_numeric($create_notes[1]->id)) 63 | ); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tests/Cases/LinkedTasksTest.php: -------------------------------------------------------------------------------- 1 | 5 | */ 6 | namespace Tests\Cases; 7 | 8 | use PHPUnit\Framework\Assert; 9 | use Ufee\Amo\Services; 10 | 11 | require_once __DIR__ . '/../TestCase.php'; 12 | 13 | class LinkedTasksTest extends \Tests\TestCase 14 | { 15 | public function testGetTasksService() 16 | { 17 | Assert::assertInstanceOf( 18 | Services\Tasks::class, $this->amo->tasks() 19 | ); 20 | } 21 | 22 | public function testUpdateLeadTask() 23 | { 24 | $lead = $this->amo->leads()->create(); 25 | $lead->name = 'Test UpdateLeadTask '.time(); 26 | $lead->save(); 27 | 28 | $task = $lead->createTask(1); 29 | $task->text = 'Test UpdateLeadTask '.time(); 30 | $task->element_type = 2; 31 | $task->element_id = $lead->id; 32 | $has_created = $task->save(); 33 | 34 | Assert::assertTrue( 35 | ($has_created && is_numeric($task->id)) 36 | ); 37 | 38 | $task->text = 'Test UpdateLeadTask NEW'; 39 | $task->save(); 40 | $task = $this->amo->tasks()->find($task->id); 41 | 42 | Assert::assertEquals( 43 | $task->text, 'Test UpdateLeadTask NEW' 44 | ); 45 | } 46 | 47 | public function testCreateTwoLeadTasks() 48 | { 49 | $lead = $this->amo->leads()->create(); 50 | $lead->name = 'Test CreateTwoLeadTasks '.time(); 51 | $lead->save(); 52 | 53 | $create_tasks = [ 54 | $lead->createTask(1), 55 | $lead->createTask(1) 56 | ]; 57 | $create_tasks[0]->text = 'Test CreateTwoLeadTasks 1 '.time(); 58 | $create_tasks[1]->text = 'Test CreateTwoLeadTasks 2 '.time(); 59 | $has_created = $this->amo->tasks()->add($create_tasks); 60 | 61 | Assert::assertTrue( 62 | ($has_created && is_numeric($create_tasks[0]->id) && is_numeric($create_tasks[1]->id)) 63 | ); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tests/Config.php: -------------------------------------------------------------------------------- 1 | 5 | */ 6 | namespace Tests; 7 | 8 | abstract class Config 9 | { 10 | /** 11 | * amoCRM API client config for tests 12 | * @return array 13 | */ 14 | public static function getAccount() 15 | { 16 | return [ 17 | 'id' => 123, 18 | 'domain' => 'testdomain', 19 | 'login' => 'test@login', 20 | 'hash' => 'testhash' 21 | ]; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | 5 | */ 6 | namespace Tests; 7 | 8 | use Ufee\Amo\Amoapi; 9 | 10 | require_once __DIR__ . '/Config.php'; 11 | 12 | class TestCase extends \PHPUnit\Framework\TestCase 13 | { 14 | /** 15 | * @var Amoapi $amo 16 | */ 17 | protected $amo; 18 | 19 | public function setUp() 20 | { 21 | $this->amo = Amoapi::setInstance( 22 | Config::getAccount() 23 | ); 24 | $this->amo->autoAuth(true); 25 | } 26 | } 27 | --------------------------------------------------------------------------------