Пример #1
0
 public function getApiDocInfo()
 {
     $base = parent::getApiDocInfo();
     $wrapper = ResourcesWrapper::getWrapper();
     $models = ['TableSchemas' => ['id' => 'TableSchemas', 'properties' => [$wrapper => ['type' => 'Array', 'description' => 'An array of table definitions.', 'items' => ['$ref' => 'TableSchema']]]], 'TableSchema' => ['id' => 'TableSchema', 'properties' => ['name' => ['type' => 'string', 'description' => 'Identifier/Name for the table.'], 'label' => ['type' => 'string', 'description' => 'Displayable singular name for the table.'], 'plural' => ['type' => 'string', 'description' => 'Displayable plural name for the table.'], 'primary_key' => ['type' => 'string', 'description' => 'Field(s), if any, that represent the primary key of each record.'], 'name_field' => ['type' => 'string', 'description' => 'Field(s), if any, that represent the name of each record.'], 'field' => ['type' => 'Array', 'description' => 'An array of available fields in each record.', 'items' => ['$ref' => 'FieldSchema']]]], 'FieldSchema' => ['id' => 'FieldSchema', 'properties' => ['name' => ['type' => 'string', 'description' => 'The API name of the field.'], 'label' => ['type' => 'string', 'description' => 'The displayable label for the field.'], 'type' => ['type' => 'string', 'description' => 'The DSP abstract data type for this field.'], 'db_type' => ['type' => 'string', 'description' => 'The native database type used for this field.'], 'is_primary_key' => ['type' => 'boolean', 'description' => 'Is this field used as/part of the primary key.'], 'validation' => ['type' => 'Array', 'description' => 'validations to be performed on this field.', 'items' => ['type' => 'string']], 'picklist' => ['type' => 'Array', 'description' => 'Selectable string values for client menus and picklist validation.', 'items' => ['type' => 'string']]]]];
     $base['models'] = array_merge($base['models'], $models);
     return $base;
 }
Пример #2
0
 public function getApiDocInfo()
 {
     $path = '/' . $this->getServiceName() . '/' . $this->getFullPathName();
     $eventPath = $this->getServiceName() . '.' . $this->getFullPathName('.');
     $name = Inflector::camelize($this->name);
     $plural = Inflector::pluralize($name);
     $words = str_replace('_', ' ', $this->name);
     $pluralWords = Inflector::pluralize($words);
     $wrapper = ResourcesWrapper::getWrapper();
     $apis = [['path' => $path, 'description' => "Operations for {$words} administration.", 'operations' => [['method' => 'GET', 'summary' => 'get' . $plural . '() - Retrieve one or more ' . $pluralWords . '.', 'nickname' => 'get' . $plural, 'type' => $plural . 'Response', 'event_name' => [$eventPath . '.list'], 'consumes' => ['application/json', 'application/xml', 'text/csv'], 'produces' => ['application/json', 'application/xml', 'text/csv'], 'parameters' => [ApiOptions::documentOption(ApiOptions::FIELDS)], 'responseMessages' => ApiDocUtilities::getCommonResponses([400, 401, 500]), 'notes' => 'List Active Directory ' . strtolower($pluralWords)]]], ['path' => $path . '/{' . strtolower($name) . '_name}', 'operations' => [['method' => 'GET', 'summary' => 'get' . $name . '() - Retrieve one ' . $words . '.', 'nickname' => 'get' . $name, 'type' => $name . 'Response', 'event_name' => $eventPath . '.read', 'parameters' => [['name' => strtolower($name) . '_name', 'description' => 'Identifier of the record to retrieve.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true], ApiOptions::documentOption(ApiOptions::FIELDS)], 'responseMessages' => ApiDocUtilities::getCommonResponses([400, 401, 500]), 'notes' => 'Use the \'fields\' parameter to limit properties that are returned. By default, all fields are returned.']], 'description' => "Operations for individual {$words} administration."]];
     $models = [$plural . 'Response' => ['id' => $plural . 'Response', 'properties' => [$wrapper => ['type' => 'array', 'description' => 'Array of records.', 'items' => ['$ref' => $name . 'Response']]]], $name . 'Response' => ['id' => $name . 'Response', 'properties' => ['objectclass' => ['type' => 'array', 'description' => 'This property identifies the class of which the object is an instance, as well as all structural or abstract superclasses from which that class is derived.'], 'cn' => ['type' => 'string', 'description' => 'Common name of the object'], 'dn' => ['type' => 'string', 'description' => 'Distinguished name of the object'], 'distinguishedname' => ['type' => 'string', 'description' => 'Distinguished name of the object'], 'whencreated' => ['type' => 'string', 'description' => 'Date/Time when object was created'], 'whenchanged' => ['type' => 'string', 'description' => 'Date/Time when object was changed'], 'objectcategory' => ['type' => 'string', 'description' => 'Shows objectCagetory attribute.']]]];
     return ['apis' => $apis, 'models' => $models];
 }
Пример #3
0
 public function getApiDocInfo()
 {
     //        $alwaysWrap = \Config::get('df.always_wrap_resources', false);
     $wrapper = ResourcesWrapper::getWrapper();
     $apis = [['path' => '/' . $this->name, 'operations' => [['method' => 'GET', 'summary' => 'getEventSubscribers() - Retrieve one or more subscribers.', 'nickname' => 'getEventSubscribers', 'type' => 'SubscribersResponse', 'event_name' => $this->name . '.subscriber.list', 'consumes' => ['application/json', 'application/xml', 'text/csv'], 'produces' => ['application/json', 'application/xml', 'text/csv'], 'parameters' => [ApiOptions::documentOption(ApiOptions::IDS), ApiOptions::documentOption(ApiOptions::FILTER), ApiOptions::documentOption(ApiOptions::LIMIT), ApiOptions::documentOption(ApiOptions::ORDER), ApiOptions::documentOption(ApiOptions::GROUP), ApiOptions::documentOption(ApiOptions::OFFSET), ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED), ApiOptions::documentOption(ApiOptions::INCLUDE_COUNT), ApiOptions::documentOption(ApiOptions::INCLUDE_SCHEMA), ApiOptions::documentOption(ApiOptions::FILE)], 'responseMessages' => ApiDocUtilities::getCommonResponses([400, 401, 500]), 'notes' => 'Use the \'ids\' or \'filter\' parameter to limit records that are returned. ' . 'By default, all records up to the maximum are returned. <br>' . 'Use the \'fields\' and \'related\' parameters to limit properties returned for each record. ' . 'By default, all fields and no relations are returned for each record. <br>' . 'Alternatively, to retrieve by record, a large list of ids, or a complicated filter, ' . 'use the POST request with X-HTTP-METHOD = GET header and post records or ids.'], ['method' => 'POST', 'summary' => 'createEventSubscribers() - Create one or more subscribers.', 'nickname' => 'createEventSubscribers', 'type' => 'SubscribersResponse', 'event_name' => $this->name . '.subscriber.create', 'consumes' => ['application/json', 'application/xml', 'text/csv'], 'produces' => ['application/json', 'application/xml', 'text/csv'], 'parameters' => [['name' => 'body', 'description' => 'Data containing name-value pairs of records to create.', 'allowMultiple' => false, 'type' => 'UsersRequest', 'paramType' => 'body', 'required' => true], ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED), ['name' => 'X-HTTP-METHOD', 'description' => 'Override request using POST to tunnel other http request, such as DELETE.', 'enum' => ['GET', 'PUT', 'PATCH', 'DELETE'], 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'header', 'required' => false]], 'responseMessages' => ApiDocUtilities::getCommonResponses([400, 401, 500]), 'notes' => 'Post data should be a single record or an array of records (shown). ' . 'By default, only the id property of the record affected is returned on success, ' . 'use \'fields\' and \'related\' to return more info.'], ['method' => 'PATCH', 'summary' => 'updateEventSubscribers() - Update one or more subscribers.', 'nickname' => 'updateEventSubscribers', 'type' => 'SubscribersResponse', 'event_name' => $this->name . '.subscriber.update', 'consumes' => ['application/json', 'application/xml', 'text/csv'], 'produces' => ['application/json', 'application/xml', 'text/csv'], 'parameters' => [['name' => 'body', 'description' => 'Data containing name-value pairs of records to update.', 'allowMultiple' => false, 'type' => 'UsersRequest', 'paramType' => 'body', 'required' => true], ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED)], 'responseMessages' => ApiDocUtilities::getCommonResponses([400, 401, 500]), 'notes' => 'Post data should be a single record or an array of records (shown). ' . 'By default, only the id property of the record is returned on success, ' . 'use \'fields\' and \'related\' to return more info.'], ['method' => 'DELETE', 'summary' => 'deleteEventSubscribers() - Delete one or more subscribers.', 'nickname' => 'deleteEventSubscribers', 'type' => 'SubscribersResponse', 'event_name' => $this->name . '.subscriber.delete', 'parameters' => [ApiOptions::documentOption(ApiOptions::IDS), ApiOptions::documentOption(ApiOptions::FORCE), ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED)], 'responseMessages' => ApiDocUtilities::getCommonResponses([400, 401, 500]), 'notes' => 'By default, only the id property of the record deleted is returned on success. ' . 'Use \'fields\' and \'related\' to return more properties of the deleted records. <br>' . 'Alternatively, to delete by record or a large list of ids, ' . 'use the POST request with X-HTTP-METHOD = DELETE header and post records or ids.']], 'description' => 'Operations for user administration.'], ['path' => '/' . $this->name . '/{id}', 'operations' => [['method' => 'GET', 'summary' => 'getEventSubscriber() - Retrieve one subscriber.', 'nickname' => 'getEventSubscriber', 'type' => 'Subscriber', 'event_name' => $this->name . '.subscriber.read', 'parameters' => [['name' => 'id', 'description' => 'Identifier of the record to retrieve.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true], ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED)], 'responseMessages' => ApiDocUtilities::getCommonResponses([400, 401, 500]), 'notes' => 'Use the \'fields\' and/or \'related\' parameter to limit properties that are returned. By default, all fields and no relations are returned.'], ['method' => 'PATCH', 'summary' => 'updateEventSubscriber() - Update one subscriber.', 'nickname' => 'updateEventSubscriber', 'type' => 'Subscriber', 'event_name' => $this->name . '.subscriber.update', 'parameters' => [['name' => 'id', 'description' => 'Identifier of the record to update.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true], ['name' => 'body', 'description' => 'Data containing name-value pairs of fields to update.', 'allowMultiple' => false, 'type' => 'UserRequest', 'paramType' => 'body', 'required' => true], ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED)], 'responseMessages' => ApiDocUtilities::getCommonResponses([400, 401, 500]), 'notes' => 'Post data should be an array of fields to update for a single record. <br>' . 'By default, only the id is returned. Use the \'fields\' and/or \'related\' parameter to return more properties.'], ['method' => 'DELETE', 'summary' => 'deleteEventSubscriber() - Delete one subscriber.', 'nickname' => 'deleteEventSubscriber', 'type' => 'Subscriber', 'event_name' => $this->name . '.subscriber.delete', 'parameters' => [['name' => 'id', 'description' => 'Identifier of the record to delete.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true], ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED)], 'responseMessages' => ApiDocUtilities::getCommonResponses([400, 401, 500]), 'notes' => 'By default, only the id is returned. Use the \'fields\' and/or \'related\' parameter to return deleted properties.']], 'description' => 'Operations for individual user administration.']];
     $models = ['SubscribersRequest' => ['id' => 'SubscribersRequest', 'properties' => [$wrapper => ['type' => 'array', 'description' => 'Array of system records.', 'items' => ['$ref' => 'Subscriber']], ApiOptions::IDS => ['type' => 'array', 'description' => 'Array of system record identifiers, used for batch GET, PUT, PATCH, and DELETE.', 'items' => ['type' => 'integer', 'format' => 'int32']]]], 'SubscribersResponse' => ['id' => 'SubscribersResponse', 'properties' => [$wrapper => ['type' => 'array', 'description' => 'Array of system records.', 'items' => ['$ref' => 'Subscriber']], 'meta' => ['type' => 'Metadata', 'description' => 'Array of metadata returned for GET requests.']]]];
     return ['apis' => $apis, 'models' => $models];
 }
Пример #4
0
 public static function getApiDocCommonModels()
 {
     $wrapper = ResourcesWrapper::getWrapper();
     return ['TableSchemas' => ['id' => 'TableSchemas', 'properties' => [$wrapper => ['type' => 'Array', 'description' => 'An array of table definitions.', 'items' => ['$ref' => 'TableSchema']]]], 'TableSchema' => ['id' => 'TableSchema', 'properties' => ['name' => ['type' => 'string', 'description' => 'Identifier/Name for the table.'], 'label' => ['type' => 'string', 'description' => 'Displayable singular name for the table.'], 'plural' => ['type' => 'string', 'description' => 'Displayable plural name for the table.'], 'primary_key' => ['type' => 'string', 'description' => 'Field(s), if any, that represent the primary key of each record.'], 'name_field' => ['type' => 'string', 'description' => 'Field(s), if any, that represent the name of each record.'], 'field' => ['type' => 'Array', 'description' => 'An array of available fields in each record.', 'items' => ['$ref' => 'FieldSchema']], 'related' => ['type' => 'Array', 'description' => 'An array of available relationships to other tables.', 'items' => ['$ref' => 'RelatedSchema']]]], 'FieldSchema' => ['id' => 'FieldSchema', 'properties' => ['name' => ['type' => 'string', 'description' => 'The API name of the field.'], 'label' => ['type' => 'string', 'description' => 'The displayable label for the field.'], 'type' => ['type' => 'string', 'description' => 'The DSP abstract data type for this field.'], 'db_type' => ['type' => 'string', 'description' => 'The native database type used for this field.'], 'length' => ['type' => 'integer', 'format' => 'int32', 'description' => 'The maximum length allowed (in characters for string, displayed for numbers).'], 'precision' => ['type' => 'integer', 'format' => 'int32', 'description' => 'Total number of places for numbers.'], 'scale' => ['type' => 'integer', 'format' => 'int32', 'description' => 'Number of decimal places allowed for numbers.'], 'default_value' => ['type' => 'string', 'description' => 'Default value for this field.'], 'required' => ['type' => 'boolean', 'description' => 'Is a value required for record creation.'], 'allow_null' => ['type' => 'boolean', 'description' => 'Is null allowed as a value.'], 'fixed_length' => ['type' => 'boolean', 'description' => 'Is the length fixed (not variable).'], 'supports_multibyte' => ['type' => 'boolean', 'description' => 'Does the data type support multibyte characters.'], 'auto_increment' => ['type' => 'boolean', 'description' => 'Does the integer field value increment upon new record creation.'], 'is_primary_key' => ['type' => 'boolean', 'description' => 'Is this field used as/part of the primary key.'], 'is_foreign_key' => ['type' => 'boolean', 'description' => 'Is this field used as a foreign key.'], 'ref_table' => ['type' => 'string', 'description' => 'For foreign keys, the referenced table name.'], 'ref_fields' => ['type' => 'string', 'description' => 'For foreign keys, the referenced table field name.'], 'validation' => ['type' => 'Array', 'description' => 'validations to be performed on this field.', 'items' => ['type' => 'string']], 'value' => ['type' => 'Array', 'description' => 'Selectable string values for client menus and picklist validation.', 'items' => ['type' => 'string']]]], 'RelatedSchema' => ['id' => 'RelatedSchema', 'properties' => ['name' => ['type' => 'string', 'description' => 'Name of the relationship.'], 'type' => ['type' => 'string', 'description' => 'Relationship type - belongs_to, has_many, many_many.'], 'ref_table' => ['type' => 'string', 'description' => 'The table name that is referenced by the relationship.'], 'ref_fields' => ['type' => 'string', 'description' => 'The field name that is referenced by the relationship.'], 'join' => ['type' => 'string', 'description' => 'The intermediate joining table used for many_many relationships.'], 'field' => ['type' => 'string', 'description' => 'The current table field that is used in the relationship.']]]];
 }
Пример #5
0
 public function getApiDocInfo()
 {
     $path = '/' . $this->getServiceName() . '/' . $this->getFullPathName();
     $eventPath = $this->getServiceName() . '.' . $this->getFullPathName('.');
     $name = Inflector::camelize($this->name);
     $plural = Inflector::pluralize($name);
     $words = str_replace('_', ' ', $this->name);
     $pluralWords = Inflector::pluralize($words);
     $wrapper = ResourcesWrapper::getWrapper();
     $apis = [['path' => $path, 'description' => "Operations for retrieving system environment.", 'operations' => [['method' => 'GET', 'summary' => 'getEnvironment() - Retrieve system environment.', 'nickname' => 'getEnvironment', 'type' => 'EnvironmentResponse', 'event_name' => $eventPath . '.list', 'consumes' => ['application/json', 'application/xml', 'text/csv'], 'produces' => ['application/json', 'application/xml', 'text/csv'], 'parameters' => [], 'responseMessages' => [], 'notes' => 'Minimum environment information given without a valid user session.' . ' More information given based on user privileges.']]]];
     $models = ['EnvironmentResponse' => ['id' => 'EnvironmentResponse', 'properties' => ['platform' => ['type' => 'array', 'description' => 'Array of system records.', 'items' => ['$ref' => $name . 'Response']], 'authentication' => ['type' => 'Metadata', 'description' => 'Array of metadata returned for GET requests.'], 'app_group' => ['type' => 'array', 'description' => 'Array of system records.', 'items' => ['$ref' => $name . 'Response']], 'no_app_group' => ['type' => 'array', 'description' => 'Array of system records.', 'items' => ['$ref' => $name . 'Response']], 'config' => ['type' => 'Metadata', 'description' => 'Array of metadata returned for GET requests.'], 'server' => ['type' => 'Metadata', 'description' => 'Array of metadata returned for GET requests.']]]];
     return ['apis' => $apis, 'models' => $models];
 }
Пример #6
0
 /**
  * @param array $array
  *
  * @return string
  */
 public static function arrayToCsv($array)
 {
     if (!is_array($array) || empty($array)) {
         return '';
     }
     $array = ArrayUtils::get($array, ResourcesWrapper::getWrapper(), ArrayUtils::get($array, 'error', $array));
     $data = [];
     if (!isset($array[0])) {
         $data[] = $array;
     } else {
         $data = $array;
     }
     $keys = array_keys(ArrayUtils::get($data, 0, []));
     // currently need to write out to file to use parser
     $tmpDir = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
     $filename = $tmpDir . 'csv_export' . time() . '.csv';
     $handle = fopen($filename, 'w');
     // build header row
     fputcsv($handle, $keys);
     foreach ($data as $row) {
         foreach ($row as $key => $value) {
             // handle objects and array non-conformist to csv output
             if (is_array($value) || is_object($value)) {
                 $row[$key] = json_encode($value);
             }
         }
         fputcsv($handle, $row);
     }
     fclose($handle);
     $csv = file_get_contents($filename);
     unlink($filename);
     return $csv;
 }
Пример #7
0
 public function getApiDocModels()
 {
     $name = Inflector::camelize($this->name);
     $plural = Inflector::pluralize($name);
     $wrapper = ResourcesWrapper::getWrapper();
     return ['ResourceList' => ['id' => 'ResourceList', 'properties' => [$wrapper => ['type' => 'array', 'description' => 'Array of accessible resources available to this service.', 'items' => ['type' => 'string']]]], $name . 'Response' => ['id' => $name . 'Response', 'properties' => [$this->getResourceIdentifier() => ['type' => 'string', 'description' => 'Identifier of the resource.']]], $plural . 'Response' => ['id' => $plural . 'Response', 'properties' => [$wrapper => ['type' => 'array', 'description' => 'Array of resources available to this service.', 'items' => ['$ref' => $name . 'Response']]]], 'Success' => ['id' => 'Success', 'properties' => ['success' => ['type' => 'boolean', 'description' => 'True when API call was successful, false or error otherwise.']]]];
 }
Пример #8
0
 /**
  * Handles DELETE action
  *
  * @return \DreamFactory\Core\Utility\ServiceResponse
  * @throws BadRequestException
  * @throws \Exception
  */
 protected function handleDELETE()
 {
     $deleteStorage = $this->request->getParameterAsBool('delete_storage');
     $fields = $this->request->getParameter('fields');
     if ($deleteStorage) {
         if (empty($fields)) {
             $fields = 'id,storage_service_id,storage_container';
         } else {
             if ($fields !== '*') {
                 $fields = explode(',', $fields);
                 if (!in_array('id', $fields)) {
                     $fields[] = 'id';
                 }
                 if (!in_array('storage_service_id', $fields)) {
                     $fields[] = 'storage_service_id';
                 }
                 if (!in_array('storage_container', $fields)) {
                     $fields[] = 'storage_container';
                 }
                 $fields = implode(',', $fields);
             }
         }
         $this->request->setParameter('fields', $fields);
     }
     $result = parent::handleDELETE();
     if ($deleteStorage) {
         $temp = $result;
         $wrapper = ResourcesWrapper::getWrapper();
         if (isset($result[$wrapper])) {
             $temp = ResourcesWrapper::unwrapResources($temp);
         }
         if (ArrayUtils::isArrayNumeric($temp)) {
             foreach ($temp as $app) {
                 static::deleteHostedAppStorage($app['id'], $app['storage_service_id'], $app['storage_container']);
             }
         } else {
             static::deleteHostedAppStorage($temp['id'], $temp['storage_service_id'], $temp['storage_container']);
         }
     }
     return $result;
 }
Пример #9
0
 /**
  * {@inheritdoc}
  */
 protected function commitTransaction($extras = null)
 {
     if (empty($this->batchRecords) && empty($this->batchIds)) {
         return null;
     }
     $updates = ArrayUtils::get($extras, 'updates');
     $ssFilters = ArrayUtils::get($extras, 'ss_filters');
     $fields = ArrayUtils::get($extras, ApiOptions::FIELDS);
     $requireMore = ArrayUtils::get($extras, 'require_more');
     $out = [];
     switch ($this->getAction()) {
         case Verbs::POST:
             $result = $this->collection->batchInsert($this->batchRecords, ['continueOnError' => false]);
             static::processResult($result);
             $out = static::cleanRecords($this->batchRecords, $fields, static::DEFAULT_ID_FIELD);
             break;
         case Verbs::PUT:
             if (empty($updates)) {
                 throw new BadRequestException('Batch operation not supported for update by records.');
             }
             $filter = [static::DEFAULT_ID_FIELD => ['$in' => $this->batchIds]];
             $criteria = static::buildCriteriaArray($filter, null, $ssFilters);
             $result = $this->collection->update($criteria, $updates, ['multiple' => true]);
             $rows = static::processResult($result);
             if (0 === $rows) {
                 throw new NotFoundException('No requested records were found to update.');
             }
             if (count($this->batchIds) !== $rows) {
                 throw new BadRequestException('Batch Error: Not all requested records were found to update.');
             }
             if ($requireMore) {
                 $fieldArray = static::buildFieldArray($fields);
                 /** @var \MongoCursor $result */
                 $result = $this->collection->find($criteria, $fieldArray);
                 $out = static::cleanRecords(iterator_to_array($result));
             } else {
                 $out = static::idsAsRecords(static::mongoIdsToIds($this->batchIds), static::DEFAULT_ID_FIELD);
             }
             break;
         case Verbs::MERGE:
         case Verbs::PATCH:
             if (empty($updates)) {
                 throw new BadRequestException('Batch operation not supported for patch by records.');
             }
             $updates = ['$set' => $updates];
             $filter = [static::DEFAULT_ID_FIELD => ['$in' => $this->batchIds]];
             $criteria = static::buildCriteriaArray($filter, null, $ssFilters);
             $result = $this->collection->update($criteria, $updates, ['multiple' => true]);
             $rows = static::processResult($result);
             if (0 === $rows) {
                 throw new NotFoundException('No requested records were found to patch.');
             }
             if (count($this->batchIds) !== $rows) {
                 throw new BadRequestException('Batch Error: Not all requested records were found to patch.');
             }
             if ($requireMore) {
                 $fieldArray = static::buildFieldArray($fields);
                 /** @var \MongoCursor $result */
                 $result = $this->collection->find($criteria, $fieldArray);
                 $out = static::cleanRecords(iterator_to_array($result));
             } else {
                 $out = static::idsAsRecords(static::mongoIdsToIds($this->batchIds), static::DEFAULT_ID_FIELD);
             }
             break;
         case Verbs::DELETE:
             $filter = [static::DEFAULT_ID_FIELD => ['$in' => $this->batchIds]];
             $criteria = static::buildCriteriaArray($filter, null, $ssFilters);
             if ($requireMore) {
                 $fieldArray = static::buildFieldArray($fields);
                 $result = $this->collection->find($criteria, $fieldArray);
                 $result = static::cleanRecords(iterator_to_array($result));
                 if (empty($result)) {
                     throw new NotFoundException('No records were found using the given identifiers.');
                 }
                 if (count($this->batchIds) !== count($result)) {
                     $errors = [];
                     foreach ($this->batchIds as $index => $id) {
                         $found = false;
                         foreach ($result as $record) {
                             if ($id == ArrayUtils::get($record, static::DEFAULT_ID_FIELD)) {
                                 $out[$index] = $record;
                                 $found = true;
                                 continue;
                             }
                         }
                         if (!$found) {
                             $errors[] = $index;
                             $out[$index] = "Record with identifier '" . print_r($id, true) . "' not found.";
                         }
                     }
                 } else {
                     $out = $result;
                 }
             } else {
                 $out = static::idsAsRecords(static::mongoIdsToIds($this->batchIds), static::DEFAULT_ID_FIELD);
             }
             $result = $this->collection->remove($criteria);
             $rows = static::processResult($result);
             if (0 === $rows) {
                 throw new NotFoundException('No records were found using the given identifiers.');
             }
             if (count($this->batchIds) !== $rows) {
                 throw new BadRequestException('Batch Error: Not all requested records were deleted.');
             }
             break;
         case Verbs::GET:
             $filter = [static::DEFAULT_ID_FIELD => ['$in' => $this->batchIds]];
             $criteria = static::buildCriteriaArray($filter, null, $ssFilters);
             $fieldArray = static::buildFieldArray($fields);
             $result = $this->collection->find($criteria, $fieldArray);
             $result = static::cleanRecords(iterator_to_array($result));
             if (empty($result)) {
                 throw new NotFoundException('No records were found using the given identifiers.');
             }
             if (count($this->batchIds) !== count($result)) {
                 $errors = [];
                 foreach ($this->batchIds as $index => $id) {
                     $found = false;
                     foreach ($result as $record) {
                         if ($id == ArrayUtils::get($record, static::DEFAULT_ID_FIELD)) {
                             $out[$index] = $record;
                             $found = true;
                             continue;
                         }
                     }
                     if (!$found) {
                         $errors[] = $index;
                         $out[$index] = "Record with identifier '" . print_r($id, true) . "' not found.";
                     }
                 }
                 if (!empty($errors)) {
                     $wrapper = ResourcesWrapper::getWrapper();
                     $context = ['error' => $errors, $wrapper => $out];
                     throw new NotFoundException('Batch Error: Not all records could be retrieved.', null, null, $context);
                 }
             }
             $out = $result;
             break;
         default:
             break;
     }
     $this->batchIds = [];
     $this->batchRecords = [];
     return $out;
 }
Пример #10
0
 public function getApiDocInfo()
 {
     $path = '/' . $this->getServiceName() . '/' . $this->getFullPathName();
     $eventPath = $this->getServiceName() . '.' . $this->getFullPathName('.');
     $name = Inflector::camelize($this->name);
     $plural = Inflector::pluralize($name);
     $words = str_replace('_', ' ', $this->name);
     $pluralWords = Inflector::pluralize($words);
     $wrapper = ResourcesWrapper::getWrapper();
     $apis = [['path' => $path, 'description' => "Operations for {$words} administration.", 'operations' => [['method' => 'GET', 'summary' => 'get' . $plural . '() - Retrieve one or more ' . $pluralWords . '.', 'nickname' => 'get' . $plural, 'type' => $plural . 'Response', 'event_name' => [$eventPath . '.list'], 'consumes' => ['application/json', 'application/xml', 'text/csv'], 'produces' => ['application/json', 'application/xml', 'text/csv'], 'parameters' => [ApiOptions::documentOption(ApiOptions::IDS), ApiOptions::documentOption(ApiOptions::FILTER), ApiOptions::documentOption(ApiOptions::LIMIT), ApiOptions::documentOption(ApiOptions::ORDER), ApiOptions::documentOption(ApiOptions::GROUP), ApiOptions::documentOption(ApiOptions::OFFSET), ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED), ApiOptions::documentOption(ApiOptions::INCLUDE_COUNT), ApiOptions::documentOption(ApiOptions::INCLUDE_SCHEMA), ApiOptions::documentOption(ApiOptions::FILE)], 'responseMessages' => ApiDocUtilities::getCommonResponses([400, 401, 500]), 'notes' => 'Use the \'ids\' or \'filter\' parameter to limit records that are returned. ' . 'By default, all records up to the maximum are returned. <br>' . 'Use the \'fields\' and \'related\' parameters to limit properties returned for each record. ' . 'By default, all fields and no relations are returned for each record. <br>' . 'Alternatively, to retrieve by record, a large list of ids, or a complicated filter, ' . 'use the POST request with X-HTTP-METHOD = GET header and post records or ids.'], ['method' => 'POST', 'summary' => 'create' . $plural . '() - Create one or more ' . $pluralWords . '.', 'nickname' => 'create' . $plural, 'type' => $plural . 'Response', 'event_name' => $eventPath . '.create', 'consumes' => ['application/json', 'application/xml', 'text/csv'], 'produces' => ['application/json', 'application/xml', 'text/csv'], 'parameters' => [['name' => 'body', 'description' => 'Data containing name-value pairs of records to create.', 'allowMultiple' => false, 'type' => $plural . 'Request', 'paramType' => 'body', 'required' => true], ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED), ['name' => 'X-HTTP-METHOD', 'description' => 'Override request using POST to tunnel other http request, such as DELETE.', 'enum' => ['GET', 'PUT', 'PATCH', 'DELETE'], 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'header', 'required' => false]], 'responseMessages' => ApiDocUtilities::getCommonResponses([400, 401, 500]), 'notes' => 'Post data should be a single record or an array of records (shown). ' . 'By default, only the id property of the record affected is returned on success, ' . 'use \'fields\' and \'related\' to return more info.'], ['method' => 'PATCH', 'summary' => 'update' . $plural . '() - Update one or more ' . $pluralWords . '.', 'nickname' => 'update' . $plural, 'type' => $plural . 'Response', 'event_name' => $eventPath . '.update', 'consumes' => ['application/json', 'application/xml', 'text/csv'], 'produces' => ['application/json', 'application/xml', 'text/csv'], 'parameters' => [['name' => 'body', 'description' => 'Data containing name-value pairs of records to update.', 'allowMultiple' => false, 'type' => $plural . 'Request', 'paramType' => 'body', 'required' => true], ApiOptions::documentOption(ApiOptions::IDS), ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED)], 'responseMessages' => ApiDocUtilities::getCommonResponses([400, 401, 500]), 'notes' => 'Post data should be a single record or an array of records (shown). ' . 'By default, only the id property of the record is returned on success, ' . 'use \'fields\' and \'related\' to return more info.'], ['method' => 'DELETE', 'summary' => 'delete' . $plural . '() - Delete one or more ' . $pluralWords . '.', 'nickname' => 'delete' . $plural, 'type' => $plural . 'Response', 'event_name' => $eventPath . '.delete', 'parameters' => [['name' => 'force', 'description' => 'Set force to true to delete all records in this table, otherwise \'ids\' parameter is required.', 'allowMultiple' => false, 'type' => 'boolean', 'paramType' => 'query', 'required' => false, 'default' => false], ApiOptions::documentOption(ApiOptions::IDS), ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED)], 'responseMessages' => ApiDocUtilities::getCommonResponses([400, 401, 500]), 'notes' => 'By default, only the id property of the record deleted is returned on success. ' . 'Use \'fields\' and \'related\' to return more properties of the deleted records. <br>' . 'Alternatively, to delete by record or a large list of ids, ' . 'use the POST request with X-HTTP-METHOD = DELETE header and post records or ids.']]], ['path' => $path . '/{id}', 'operations' => [['method' => 'GET', 'summary' => 'get' . $name . '() - Retrieve one ' . $words . '.', 'nickname' => 'get' . $name, 'type' => $name . 'Response', 'event_name' => $eventPath . '.read', 'parameters' => [['name' => 'id', 'description' => 'Identifier of the record to retrieve.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true], ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED)], 'responseMessages' => ApiDocUtilities::getCommonResponses([400, 401, 500]), 'notes' => 'Use the \'fields\' and/or \'related\' parameter to limit properties that are returned. By default, all fields and no relations are returned.'], ['method' => 'PATCH', 'summary' => 'update' . $name . '() - Update one ' . $words . '.', 'nickname' => 'update' . $name, 'type' => $name . 'Response', 'event_name' => $eventPath . '.update', 'parameters' => [['name' => 'id', 'description' => 'Identifier of the record to update.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true], ['name' => 'body', 'description' => 'Data containing name-value pairs of fields to update.', 'allowMultiple' => false, 'type' => $name . 'Request', 'paramType' => 'body', 'required' => true], ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED)], 'responseMessages' => ApiDocUtilities::getCommonResponses([400, 401, 500]), 'notes' => 'Post data should be an array of fields to update for a single record. <br>' . 'By default, only the id is returned. Use the \'fields\' and/or \'related\' parameter to return more properties.'], ['method' => 'DELETE', 'summary' => 'delete' . $name . '() - Delete one ' . $words . '.', 'nickname' => 'delete' . $name, 'type' => $name . 'Response', 'event_name' => $eventPath . '.delete', 'parameters' => [['name' => 'id', 'description' => 'Identifier of the record to delete.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true], ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED)], 'responseMessages' => ApiDocUtilities::getCommonResponses([400, 401, 500]), 'notes' => 'By default, only the id is returned. Use the \'fields\' and/or \'related\' parameter to return deleted properties.']], 'description' => "Operations for individual {$words} administration."]];
     $models = [$plural . 'Request' => ['id' => $plural . 'Request', 'properties' => [$wrapper => ['type' => 'array', 'description' => 'Array of system records.', 'items' => ['$ref' => $name . 'Request']], ApiOptions::IDS => ['type' => 'array', 'description' => 'Array of system record identifiers, used for batch GET, PUT, PATCH, and DELETE.', 'items' => ['type' => 'integer', 'format' => 'int32']]]], $plural . 'Response' => ['id' => $plural . 'Response', 'properties' => [$wrapper => ['type' => 'array', 'description' => 'Array of system records.', 'items' => ['$ref' => $name . 'Response']], 'meta' => ['type' => 'Metadata', 'description' => 'Array of metadata returned for GET requests.']]], 'Metadata' => ['id' => 'Metadata', 'properties' => ['schema' => ['type' => 'array', 'description' => 'Array of table schema.', 'items' => ['type' => 'string']], 'count' => ['type' => 'integer', 'format' => 'int32', 'description' => 'Record count returned for GET requests.']]]];
     $model = $this->getModel();
     if ($model) {
         $temp = $model->toApiDocsModel($name);
         if ($temp) {
             $models = array_merge($models, $temp);
         }
     }
     return ['apis' => $apis, 'models' => $models];
 }
Пример #11
0
 public function getApiDocModels()
 {
     $name = Inflector::camelize($this->name);
     $plural = Inflector::pluralize($name);
     $wrapper = ResourcesWrapper::getWrapper();
     return [$plural . 'List' => ['id' => $plural . 'List', 'properties' => [$wrapper => ['type' => 'array', 'description' => 'Array of accessible resources available to this path.', 'items' => ['type' => 'string']]]], $name . 'Response' => ['id' => $name . 'Response', 'properties' => [$this->getResourceIdentifier() => ['type' => 'string', 'description' => 'Identifier of the resource.']]], $plural . 'Response' => ['id' => $plural . 'Response', 'properties' => [$wrapper => ['type' => 'array', 'description' => 'Array of resources available to this path.', 'items' => ['$ref' => $name . 'Response']]]]];
 }
Пример #12
0
 /**
  * {@inheritdoc}
  */
 protected function commitTransaction($extras = null)
 {
     if (empty($this->batchRecords) && empty($this->batchIds)) {
         if (isset($this->transaction)) {
             $this->transaction->commit();
         }
         return null;
     }
     $updates = ArrayUtils::get($extras, 'updates');
     $ssFilters = ArrayUtils::get($extras, 'ss_filters');
     $fields = ArrayUtils::get($extras, ApiOptions::FIELDS);
     $idFields = ArrayUtils::get($extras, 'id_fields');
     $related = ArrayUtils::get($extras, 'related');
     $requireMore = ArrayUtils::getBool($extras, 'require_more') || !empty($related);
     $allowRelatedDelete = ArrayUtils::getBool($extras, 'allow_related_delete', false);
     $relatedInfo = $this->describeTableRelated($this->transactionTable);
     $where = [];
     $params = [];
     $idName = isset($this->tableIdsInfo, $this->tableIdsInfo[0], $this->tableIdsInfo[0]->name) ? $this->tableIdsInfo[0]->name : null;
     if (empty($idName)) {
         throw new BadRequestException('No valid identifier found for this table.');
     }
     if (!empty($this->batchRecords)) {
         if (is_array($this->batchRecords[0])) {
             $temp = [];
             foreach ($this->batchRecords as $record) {
                 $temp[] = ArrayUtils::get($record, $idName);
             }
             $where[] = ['in', $idName, $temp];
         } else {
             $where[] = ['in', $idName, $this->batchRecords];
         }
     } else {
         $where[] = ['in', $idName, $this->batchIds];
     }
     $serverFilter = $this->buildQueryStringFromData($ssFilters, $params);
     if (!empty($serverFilter)) {
         $where[] = $serverFilter;
     }
     if (count($where) > 1) {
         array_unshift($where, 'AND');
     } else {
         $where = $where[0];
     }
     $out = [];
     $action = $this->getAction();
     if (!empty($this->batchRecords)) {
         if (1 == count($this->tableIdsInfo)) {
             // records are used to retrieve extras
             // ids array are now more like records
             $fields = empty($fields) ? $idFields : $fields;
             $result = $this->parseFieldsForSqlSelect($fields, $this->tableFieldsInfo);
             $bindings = ArrayUtils::get($result, 'bindings');
             $fields = ArrayUtils::get($result, 'fields');
             $fields = empty($fields) ? '*' : $fields;
             $result = $this->recordQuery($this->transactionTable, $fields, $where, $params, $bindings, $extras);
             if (empty($result)) {
                 throw new NotFoundException('No records were found using the given identifiers.');
             }
             $out = $result;
         } else {
             $out = $this->retrieveRecords($this->transactionTable, $this->batchRecords, $extras);
         }
         $this->batchRecords = [];
     } elseif (!empty($this->batchIds)) {
         /** @var Command $command */
         $command = $this->dbConn->createCommand();
         switch ($action) {
             case Verbs::PUT:
             case Verbs::MERGE:
             case Verbs::PATCH:
                 if (!empty($updates)) {
                     $parsed = $this->parseRecord($updates, $this->tableFieldsInfo, $ssFilters, true);
                     if (!empty($parsed)) {
                         $rows = $command->update($this->transactionTable, $parsed, $where, $params);
                         if (0 >= $rows) {
                             throw new NotFoundException('No records were found using the given identifiers.');
                         }
                         if (count($this->batchIds) !== $rows) {
                             throw new BadRequestException('Batch Error: Not all requested records could be updated.');
                         }
                     }
                     foreach ($this->batchIds as $id) {
                         if (!empty($relatedInfo)) {
                             $this->updateRelations($this->transactionTable, $updates, $id, $relatedInfo, $allowRelatedDelete);
                         }
                     }
                     if ($requireMore) {
                         $fields = empty($fields) ? $idFields : $fields;
                         $result = $this->parseFieldsForSqlSelect($fields, $this->tableFieldsInfo);
                         $bindings = ArrayUtils::get($result, 'bindings');
                         $fields = ArrayUtils::get($result, 'fields');
                         $fields = empty($fields) ? '*' : $fields;
                         $result = $this->recordQuery($this->transactionTable, $fields, $where, $params, $bindings, $extras);
                         if (empty($result)) {
                             throw new NotFoundException('No records were found using the given identifiers.');
                         }
                         $out = $result;
                     }
                 }
                 break;
             case Verbs::DELETE:
                 if ($requireMore) {
                     $fields = empty($fields) ? $idFields : $fields;
                     $result = $this->parseFieldsForSqlSelect($fields, $this->tableFieldsInfo);
                     $bindings = ArrayUtils::get($result, 'bindings');
                     $fields = ArrayUtils::get($result, 'fields');
                     $fields = empty($fields) ? '*' : $fields;
                     $result = $this->recordQuery($this->transactionTable, $fields, $where, $params, $bindings, $extras);
                     if (count($this->batchIds) !== count($result)) {
                         $errors = [];
                         foreach ($this->batchIds as $index => $id) {
                             $found = false;
                             if (empty($result)) {
                                 foreach ($result as $record) {
                                     if ($id == ArrayUtils::get($record, $idName)) {
                                         $out[$index] = $record;
                                         $found = true;
                                         continue;
                                     }
                                 }
                             }
                             if (!$found) {
                                 $errors[] = $index;
                                 $out[$index] = "Record with identifier '" . print_r($id, true) . "' not found.";
                             }
                         }
                     } else {
                         $out = $result;
                     }
                 }
                 $rows = $command->delete($this->transactionTable, $where, $params);
                 if (count($this->batchIds) !== $rows) {
                     throw new BadRequestException('Batch Error: Not all requested records were deleted.');
                 }
                 break;
             case Verbs::GET:
                 $fields = empty($fields) ? $idFields : $fields;
                 $result = $this->parseFieldsForSqlSelect($fields, $this->tableFieldsInfo);
                 $bindings = ArrayUtils::get($result, 'bindings');
                 $fields = ArrayUtils::get($result, 'fields');
                 $fields = empty($fields) ? '*' : $fields;
                 $result = $this->recordQuery($this->transactionTable, $fields, $where, $params, $bindings, $extras);
                 if (empty($result)) {
                     throw new NotFoundException('No records were found using the given identifiers.');
                 }
                 if (count($this->batchIds) !== count($result)) {
                     $errors = [];
                     foreach ($this->batchIds as $index => $id) {
                         $found = false;
                         foreach ($result as $record) {
                             if ($id == ArrayUtils::get($record, $idName)) {
                                 $out[$index] = $record;
                                 $found = true;
                                 continue;
                             }
                         }
                         if (!$found) {
                             $errors[] = $index;
                             $out[$index] = "Record with identifier '" . print_r($id, true) . "' not found.";
                         }
                     }
                     if (!empty($errors)) {
                         $context = ['error' => $errors, ResourcesWrapper::getWrapper() => $out];
                         throw new NotFoundException('Batch Error: Not all records could be retrieved.', null, null, $context);
                     }
                 }
                 $out = $result;
                 break;
             default:
                 break;
         }
         if (empty($out)) {
             $out = [];
             foreach ($this->batchIds as $id) {
                 $out[] = [$idName => $id];
             }
         }
         $this->batchIds = [];
     }
     if (isset($this->transaction)) {
         $this->transaction->commit();
     }
     return $out;
 }
Пример #13
0
 public function getApiDocInfo()
 {
     $path = '/' . $this->getServiceName() . '/' . $this->getFullPathName();
     $eventPath = $this->getServiceName() . '.' . $this->getFullPathName('.');
     $base = parent::getApiDocInfo();
     $tables = $this->listResources();
     $commonResponses = ApiDocUtilities::getCommonResponses();
     $wrapper = ResourcesWrapper::getWrapper();
     $apis = [['path' => $path . '/{table_name}', 'description' => 'Operations for table records administration.', 'operations' => [['method' => 'GET', 'summary' => 'getRecords() - Retrieve one or more records.', 'nickname' => 'getRecords', 'notes' => 'Set the <b>filter</b> parameter to a SQL WHERE clause (optional native filter accepted in some scenarios) ' . 'to limit records returned or leave it blank to return all records up to the maximum limit.<br/> ' . 'Set the <b>limit</b> parameter with or without a filter to return a specific amount of records.<br/> ' . 'Use the <b>offset</b> parameter along with the <b>limit</b> parameter to page through sets of records.<br/> ' . 'Set the <b>order</b> parameter to SQL ORDER_BY clause containing field and optional direction (<field_name> [ASC|DESC]) to order the returned records.<br/> ' . 'Alternatively, to send the <b>filter</b> with or without <b>params</b> as posted data, ' . 'use the getRecordsByPost() POST request and post a filter with or without params.<br/>' . 'Pass the identifying field values as a comma-separated list in the <b>ids</b> parameter.<br/> ' . 'Use the <b>id_field</b> and <b>id_type</b> parameters to override or specify detail for identifying fields where applicable.<br/> ' . 'Alternatively, to send the <b>ids</b> as posted data, use the getRecordsByPost() POST request.<br/> ' . 'Use the <b>fields</b> parameter to limit properties returned for each record. ' . 'By default, all fields are returned for all records. ', 'type' => 'RecordsResponse', 'event_name' => [$eventPath . '.{table_name}.select', $eventPath . '.table_selected'], 'parameters' => [['name' => 'table_name', 'description' => 'Name of the table to perform operations on.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true, 'enum' => $tables], ApiOptions::documentOption(ApiOptions::FILTER), ApiOptions::documentOption(ApiOptions::LIMIT), ApiOptions::documentOption(ApiOptions::ORDER), ApiOptions::documentOption(ApiOptions::GROUP), ApiOptions::documentOption(ApiOptions::OFFSET), ApiOptions::documentOption(ApiOptions::INCLUDE_COUNT), ApiOptions::documentOption(ApiOptions::IDS), ApiOptions::documentOption(ApiOptions::ID_FIELD), ApiOptions::documentOption(ApiOptions::ID_TYPE), ApiOptions::documentOption(ApiOptions::CONTINUES), ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED), ApiOptions::documentOption(ApiOptions::INCLUDE_SCHEMA), ApiOptions::documentOption(ApiOptions::FILE)], 'responseMessages' => $commonResponses], ['method' => 'POST', 'summary' => 'createRecords() - Create one or more records.', 'nickname' => 'createRecords', 'notes' => 'Posted data should be an array of records wrapped in a <b>record</b> element.<br/> ' . 'By default, only the id property of the record is returned on success. ' . 'Use <b>fields</b> parameter to return more info.', 'type' => 'RecordsResponse', 'event_name' => [$eventPath . '.{table_name}.insert', $eventPath . '.table_inserted'], 'parameters' => [['name' => 'table_name', 'description' => 'Name of the table to perform operations on.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true, 'enum' => $tables], ['name' => 'body', 'description' => 'Data containing name-value pairs of records to create.', 'allowMultiple' => false, 'type' => 'RecordsRequest', 'paramType' => 'body', 'required' => true], ApiOptions::documentOption(ApiOptions::ID_FIELD), ApiOptions::documentOption(ApiOptions::ID_TYPE), ApiOptions::documentOption(ApiOptions::CONTINUES), ApiOptions::documentOption(ApiOptions::ROLLBACK), ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED), ['name' => 'X-HTTP-METHOD', 'description' => 'Override request using POST to tunnel other http request, such as DELETE or GET passing a payload.', 'enum' => ['GET'], 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'header', 'required' => false]], 'responseMessages' => $commonResponses], ['method' => 'PUT', 'summary' => 'replaceRecords() - Update (replace) one or more records.', 'nickname' => 'replaceRecords', 'notes' => 'Post data should be an array of records wrapped in a <b>' . $wrapper . '</b> tag.<br/> ' . 'If ids or filter is used, posted body should be a single record with name-value pairs ' . 'to update, wrapped in a <b>' . $wrapper . '</b> tag.<br/> ' . 'Ids can be included via URL parameter or included in the posted body.<br/> ' . 'Filter can be included via URL parameter or included in the posted body.<br/> ' . 'By default, only the id property of the record is returned on success. ' . 'Use <b>fields</b> parameter to return more info.', 'type' => 'RecordsResponse', 'event_name' => [$eventPath . '.{table_name}.update', $eventPath . '.table_updated'], 'parameters' => [['name' => 'table_name', 'description' => 'Name of the table to perform operations on.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true, 'enum' => $tables], ['name' => 'body', 'description' => 'Data containing name-value pairs of records to update.', 'allowMultiple' => false, 'type' => 'RecordsRequest', 'paramType' => 'body', 'required' => true], ApiOptions::documentOption(ApiOptions::IDS), ApiOptions::documentOption(ApiOptions::ID_FIELD), ApiOptions::documentOption(ApiOptions::ID_TYPE), ApiOptions::documentOption(ApiOptions::CONTINUES), ApiOptions::documentOption(ApiOptions::ROLLBACK), ApiOptions::documentOption(ApiOptions::FILTER), ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED)], 'responseMessages' => $commonResponses], ['method' => 'PATCH', 'summary' => 'updateRecords() - Update (patch) one or more records.', 'nickname' => 'updateRecords', 'notes' => 'Post data should be an array of records containing at least the identifying fields for each record.<br/> ' . 'Posted body should be a single record with name-value pairs to update wrapped in a <b>record</b> tag.<br/> ' . 'Ids can be included via URL parameter or included in the posted body.<br/> ' . 'Filter can be included via URL parameter or included in the posted body.<br/> ' . 'By default, only the id property of the record is returned on success. ' . 'Use <b>fields</b> parameter to return more info.', 'type' => 'RecordsResponse', 'event_name' => [$eventPath . '.{table_name}.update', $eventPath . '.table_updated'], 'parameters' => [['name' => 'table_name', 'description' => 'Name of the table to perform operations on.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true, 'enum' => $tables], ['name' => 'body', 'description' => 'A single record containing name-value pairs of fields to update.', 'allowMultiple' => false, 'type' => 'RecordsRequest', 'paramType' => 'body', 'required' => true], ApiOptions::documentOption(ApiOptions::IDS), ApiOptions::documentOption(ApiOptions::ID_FIELD), ApiOptions::documentOption(ApiOptions::ID_TYPE), ApiOptions::documentOption(ApiOptions::CONTINUES), ApiOptions::documentOption(ApiOptions::ROLLBACK), ApiOptions::documentOption(ApiOptions::FILTER), ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED)], 'responseMessages' => $commonResponses], ['method' => 'DELETE', 'summary' => 'deleteRecords() - Delete one or more records.', 'nickname' => 'deleteRecords', 'notes' => 'Set the <b>ids</b> parameter to a list of record identifying (primary key) values to delete specific records.<br/> ' . 'Alternatively, to delete records by a large list of ids, pass the ids in the <b>body</b>.<br/> ' . 'By default, only the id property of the record is returned on success, use <b>fields</b> to return more info. ' . 'Set the <b>filter</b> parameter to a SQL WHERE clause to delete specific records, ' . 'otherwise set <b>force</b> to true to clear the table.<br/> ' . 'Alternatively, to delete by a complicated filter or to use parameter replacement, pass the filter with or without params as the <b>body</b>.<br/> ' . 'By default, only the id property of the record is returned on success, use <b>fields</b> to return more info. ' . 'Set the <b>body</b> to an array of records, minimally including the identifying fields, to delete specific records.<br/> ' . 'By default, only the id property of the record is returned on success, use <b>fields</b> to return more info. ', 'type' => 'RecordsResponse', 'event_name' => [$eventPath . '.{table_name}.delete', $eventPath . '.table_deleted'], 'parameters' => [['name' => 'table_name', 'description' => 'Name of the table to perform operations on.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true, 'enum' => $tables], ['name' => 'body', 'description' => 'Data containing ids of records to delete.', 'allowMultiple' => false, 'type' => 'RecordsRequest', 'paramType' => 'body', 'required' => false], ApiOptions::documentOption(ApiOptions::IDS), ApiOptions::documentOption(ApiOptions::ID_FIELD), ApiOptions::documentOption(ApiOptions::ID_TYPE), ApiOptions::documentOption(ApiOptions::CONTINUES), ApiOptions::documentOption(ApiOptions::ROLLBACK), ApiOptions::documentOption(ApiOptions::FILTER), ApiOptions::documentOption(ApiOptions::FORCE), ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED)], 'responseMessages' => $commonResponses]]], ['path' => $path . '/{table_name}/{id}', 'description' => 'Operations for single record administration.', 'operations' => [['method' => 'GET', 'summary' => 'getRecord() - Retrieve one record by identifier.', 'nickname' => 'getRecord', 'notes' => 'Use the <b>fields</b> parameter to limit properties that are returned. ' . 'By default, all fields are returned.', 'type' => 'RecordResponse', 'event_name' => [$eventPath . '.{table_name}.{id}.select', $eventPath . '.record_selected'], 'parameters' => [['name' => 'table_name', 'description' => 'Name of the table to perform operations on.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true, 'enum' => $tables], ['name' => 'id', 'description' => 'Identifier of the record to retrieve.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true], ApiOptions::documentOption(ApiOptions::ID_FIELD), ApiOptions::documentOption(ApiOptions::ID_TYPE), ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED)], 'responseMessages' => $commonResponses], ['method' => 'PUT', 'summary' => 'replaceRecord() - Replace the content of one record by identifier.', 'nickname' => 'replaceRecord', 'notes' => 'Post data should be an array of fields for a single record.<br/> ' . 'Use the <b>fields</b> parameter to return more properties. By default, the id is returned.', 'type' => 'RecordResponse', 'event_name' => [$eventPath . '.{table_name}.{id}.update', $eventPath . '.record_updated'], 'parameters' => [['name' => 'table_name', 'description' => 'Name of the table to perform operations on.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true, 'enum' => $tables], ['name' => 'id', 'description' => 'Identifier of the record to update.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true], ['name' => 'body', 'description' => 'Data containing name-value pairs of the replacement record.', 'allowMultiple' => false, 'type' => 'RecordRequest', 'paramType' => 'body', 'required' => true], ApiOptions::documentOption(ApiOptions::ID_FIELD), ApiOptions::documentOption(ApiOptions::ID_TYPE), ApiOptions::documentOption(ApiOptions::FIELDS), ApiOptions::documentOption(ApiOptions::RELATED)], 'responseMessages' => $commonResponses], ['method' => 'PATCH', 'summary' => 'updateRecord() - Update (patch) one record by identifier.', 'nickname' => 'updateRecord', 'notes' => 'Post data should be an array of fields for a single record.<br/> ' . 'Use the <b>fields</b> parameter to return more properties. By default, the id is returned.', 'type' => 'RecordResponse', 'event_name' => [$eventPath . '.{table_name}.{id}.update', $eventPath . '.record_updated'], 'parameters' => [['name' => 'table_name', 'description' => 'The name of the table you want to update.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true, 'enum' => $tables], ['name' => 'id', 'description' => 'Identifier of the record to update.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true], ['name' => 'body', 'description' => 'Data containing name-value pairs of the fields to update.', 'allowMultiple' => false, 'type' => 'RecordRequest', 'paramType' => 'body', 'required' => true], ApiOptions::documentOption(ApiOptions::ID_FIELD), ApiOptions::documentOption(ApiOptions::ID_TYPE), ApiOptions::documentOption(ApiOptions::FIELDS)], 'responseMessages' => $commonResponses], ['method' => 'DELETE', 'summary' => 'deleteRecord() - Delete one record by identifier.', 'nickname' => 'deleteRecord', 'notes' => 'Use the <b>fields</b> parameter to return more deleted properties. By default, the id is returned.', 'type' => 'RecordResponse', 'event_name' => [$eventPath . '.{table_name}.{id}.delete', $eventPath . '.record_deleted'], 'parameters' => [['name' => 'table_name', 'description' => 'Name of the table to perform operations on.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true, 'enum' => $tables], ['name' => 'id', 'description' => 'Identifier of the record to delete.', 'allowMultiple' => false, 'type' => 'string', 'paramType' => 'path', 'required' => true], ApiOptions::documentOption(ApiOptions::ID_FIELD), ApiOptions::documentOption(ApiOptions::ID_TYPE), ApiOptions::documentOption(ApiOptions::FIELDS)], 'responseMessages' => $commonResponses]]]];
     $base['apis'] = array_merge($base['apis'], $apis);
     return $base;
 }
Пример #14
0
 /**
  * @param       $records
  * @param array $params
  * @param bool  $singlePayload
  *
  * @return array|mixed
  * @throws BadRequestException
  * @throws \Exception
  */
 public static function bulkDelete($records, $params = [], $singlePayload = false)
 {
     if (empty($records)) {
         throw new BadRequestException('There is no record in the request.');
     }
     $response = [];
     $transaction = null;
     $errors = [];
     $singleRow = 1 === count($records) ? true : false;
     $rollback = ArrayUtils::getBool($params, ApiOptions::ROLLBACK);
     $continue = ArrayUtils::getBool($params, ApiOptions::CONTINUES);
     try {
         //	Start a transaction
         if (!$singleRow && $rollback) {
             DB::beginTransaction();
             $transaction = true;
         }
         foreach ($records as $key => $record) {
             try {
                 $m = new static();
                 $pk = $m->getPrimaryKey();
                 $id = ArrayUtils::get($record, $pk);
                 $response[$key] = static::deleteInternal($id, $record, $params);
             } catch (\Exception $ex) {
                 if ($singleRow) {
                     throw $ex;
                 }
                 if ($rollback && $transaction) {
                     DB::rollBack();
                     throw $ex;
                 }
                 // track the index of the error and copy error to results
                 $errors[] = $key;
                 $response[$key] = $ex->getMessage();
                 if (!$continue) {
                     break;
                 }
             }
         }
     } catch (\Exception $ex) {
         throw $ex;
     }
     if (!empty($errors)) {
         $msg = ['errors' => $errors, ResourcesWrapper::getWrapper() => $response];
         throw new BadRequestException("Batch Error: Not all parts of the request were successful.", null, null, $msg);
     }
     //	Commit
     if ($transaction) {
         try {
             DB::commit();
         } catch (\Exception $ex) {
             throw $ex;
         }
     }
     return $singlePayload ? current($response) : $response;
 }
Пример #15
0
 public function getApiDocModels()
 {
     $wrapper = ResourcesWrapper::getWrapper();
     $base = parent::getApiDocModels();
     $models = ['Tables' => ['id' => 'Tables', 'properties' => [$wrapper => ['type' => 'array', 'description' => 'Array of tables and their properties.', 'items' => ['$ref' => 'Table']]]], 'Table' => ['id' => 'Table', 'properties' => ['name' => ['type' => 'string', 'description' => 'Name of the table.']]]];
     return array_merge($base, $models);
 }