/** * Handles all GET requests. * * @return array */ protected function handleGET() { $this->parent->authenticateAdminUser(); $groupName = $this->resource; $username = $this->request->getParameter('user'); $fields = $this->request->getParameter(ApiOptions::FIELDS, ApiOptions::FIELDS_ALL); $attributes = []; if ('*' !== $fields) { $attributes = explode(',', $fields); } if (!empty($username)) { $asList = $this->request->getParameterAsBool(ApiOptions::AS_LIST); if ($asList) { $attributes = ['samaccountname']; } $resources = $this->provider->getGroups($username, $attributes); } else { if (empty($groupName)) { $asList = $this->request->getParameterAsBool(ApiOptions::AS_LIST); if ($asList) { $attributes = ['samaccountname']; } $resources = $this->provider->listGroup($attributes); } else { $adGroup = $this->provider->getGroupByCn($groupName); $resources = $adGroup->getData($attributes); } } return ResourcesWrapper::cleanResources($resources); }
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; }
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]; }
<?php if (\Request::method() === 'POST') { $pin = \Request::input('pin'); $state = \Request::input('state'); if (empty($pin) && $pin !== 0 || empty($state) && $state !== 0) { throw new \DreamFactory\Core\Exceptions\BadRequestException('Please provide pin and state data'); } $gpio = new \a15lam\RpiGpio\GPIO(); $result = $gpio->write($pin, $state); $result = empty($result) ? ['success' => true] : $result; return \DreamFactory\Core\Utility\ResourcesWrapper::cleanResources($result); } else { throw new \DreamFactory\Core\Exceptions\BadRequestException('Only POST is accepted'); }
/** * Returns CSV payload data * * @param null $key * @param null $default * * @return array|mixed|null * @throws \DreamFactory\Core\Exceptions\BadRequestException */ protected function csv($key = null, $default = null) { if (!empty($this->contentAsArray)) { if (null === $key) { return $this->contentAsArray; } else { return ArrayUtils::get($this->contentAsArray, $key, $default); } } $content = $this->getContent(); $data = DataFormatter::csvToArray($content); if (!empty($content) && empty($data)) { throw new BadRequestException('Invalid CSV payload supplied.'); } $payload = ResourcesWrapper::wrapResources($data); // Store the content so that formatting is only done once. $this->contentAsArray = empty($payload) ? [] : $payload; $this->content = $content; if (null === $key) { if (empty($payload)) { return []; } else { return $payload; } } else { if (empty($payload)) { return $default; } else { return ArrayUtils::get($payload, $key, $default); } } }
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.']]]]; }
/** * {@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; }
/** * 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; }
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.']]]]; }
/** * Handles GET action * * @return mixed */ protected function handleGET() { $resources = $this->getResources(); if (is_array($resources)) { $includeAccess = $this->request->getParameterAsBool(ApiOptions::INCLUDE_ACCESS); $asList = $this->request->getParameterAsBool(ApiOptions::AS_LIST); $idField = $this->request->getParameter(ApiOptions::ID_FIELD, $this->getResourceIdentifier()); $fields = $this->request->getParameter(ApiOptions::FIELDS); if (!$asList && $includeAccess) { foreach ($resources as &$resource) { if (is_array($resource)) { $name = ArrayUtils::get($resource, $idField); $resource['access'] = VerbsMask::maskToArray($this->getPermissions($name)); } } } return ResourcesWrapper::cleanResources($resources, $asList, $idField, $fields); } return $resources; }
/** * Handles GET action * * @return array * @throws NotFoundException */ protected function handleGET() { if (empty($this->resource)) { $service = $this->request->getParameter('service'); $type = $this->request->getParameter('type'); $onlyScripted = $this->request->getParameterAsBool('only_scripted'); if ($onlyScripted) { switch ($type) { case 'process': $scripts = EventScript::where('affects_process', 1)->lists('name')->all(); break; case 'broadcast': $scripts = EventScript::where('affects_process', 0)->lists('name')->all(); break; default: $scripts = EventScript::lists('name')->all(); break; } return ResourcesWrapper::cleanResources(array_values(array_unique($scripts))); } $results = $this->getEventMap(); $allEvents = []; switch ($type) { case 'process': $results = ArrayUtils::get($results, 'process', []); foreach ($results as $serviceKey => $apis) { if (!empty($service) && 0 !== strcasecmp($service, $serviceKey)) { unset($results[$serviceKey]); } else { foreach ($apis as $path => $operations) { foreach ($operations['verb'] as $method => $events) { $allEvents = array_merge($allEvents, $events); } } } } break; case 'broadcast': $results = ArrayUtils::get($results, 'broadcast', []); foreach ($results as $serviceKey => $apis) { if (!empty($service) && 0 !== strcasecmp($service, $serviceKey)) { unset($results[$serviceKey]); } else { foreach ($apis as $path => $operations) { foreach ($operations['verb'] as $method => $events) { $allEvents = array_merge($allEvents, $events); } } } } break; default: foreach ($results as $type => $services) { foreach ($services as $serviceKey => $apis) { if (!empty($service) && 0 !== strcasecmp($service, $serviceKey)) { unset($results[$type][$serviceKey]); } else { foreach ($apis as $path => $operations) { foreach ($operations['verb'] as $method => $events) { $allEvents = array_merge($allEvents, $events); } } } } } break; } if (!$this->request->getParameterAsBool(ApiOptions::AS_LIST)) { return $results; } return ResourcesWrapper::cleanResources(array_values(array_unique($allEvents))); } $related = $this->request->getParameter(ApiOptions::RELATED); if (!empty($related)) { $related = explode(',', $related); } else { $related = []; } // Single script by name $fields = [ApiOptions::FIELDS_ALL]; if (null !== ($value = $this->request->getParameter(ApiOptions::FIELDS))) { $fields = explode(',', $value); } if (null === ($foundModel = EventScript::with($related)->find($this->resource, $fields))) { throw new NotFoundException("Script not found."); } return ResponseFactory::create($foundModel->toArray(), $this->nativeFormat); }
/** * @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; }
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']]]]]; }
/** * {@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; }
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; }
/** * @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; }
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); }
/** * Execute the console command. * * @return mixed */ public function handle() { if (!class_exists('DreamFactory\\Core\\ADLdap\\Services\\ADLdap')) { $this->error('Command unavailable. Please install \'dreamfactory/df-adldap\' package to use this command.'); return; } try { $serviceName = $this->argument('service'); $username = $this->option('username'); $password = $this->option('password'); /** @type ADLdap $service */ $service = ServiceHandler::getService($serviceName); $serviceModel = Service::find($service->getServiceId()); $serviceType = $serviceModel->serviceType()->first(); $serviceGroup = $serviceType->group; if ($serviceGroup !== ServiceTypeGroups::LDAP) { throw new BadRequestException('Invalid service name [' . $serviceName . ']. Please use a valid Active Directory service'); } $this->line('Contacting your Active Directory server...'); $service->authenticateAdminUser($username, $password); $this->line('Fetching Active Directory groups...'); $groups = $service->getDriver()->listGroup(['dn', 'description']); $roles = []; foreach ($groups as $group) { $dfRole = RoleADLdap::whereDn($group['dn'])->first(); if (empty($dfRole)) { $role = ['name' => static::dnToRoleName($group['dn']), 'description' => $group['description'], 'is_active' => true, 'role_adldap_by_role_id' => [['dn' => $group['dn']]]]; $this->info('|--------------------------------------------------------------------'); $this->info('| DN: ' . $group['dn']); $this->info('| Role Name: ' . $role['name']); $this->info('| Description: ' . $role['description']); $this->info('|--------------------------------------------------------------------'); $roles[] = $role; } } $roleCount = count($roles); if ($roleCount > 0) { $this->warn('Total Roles to import: [' . $roleCount . ']'); if ($this->confirm('The above roles will be imported into your DreamFactroy instance based on your Active Directory groups. Do you wish to continue?')) { $this->line('Importing Roles...'); $payload = ResourcesWrapper::wrapResources($roles); ServiceHandler::handleRequest(Verbs::POST, 'system', 'role', ['continue' => true], $payload); $this->info('Successfully imported all Active Directory groups as Roles.'); } else { $this->info('Aborted import process. No Roles were imported'); } } else { if (count($groups) > 0 && $roleCount === 0) { $this->info('All groups found on the Active Directory server are already imported.'); } else { $this->warn('No group was found on Active Directory server.'); } } } catch (RestException $e) { $this->error($e->getMessage()); if ($this->option('verbose')) { $this->error(print_r($e->getContext(), true)); } } catch (\Exception $e) { $this->error($e->getMessage()); } }
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]; }
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]; }
/** * Handles DELETE actions. * * @return \DreamFactory\Core\Utility\ServiceResponse * @throws BadRequestException */ protected function handleDELETE() { $force = $this->request->getParameterAsBool('force', false); if (empty($this->folderPath)) { // delete just folders and files from the container if (!empty($content = ResourcesWrapper::unwrapResources($this->request->getPayloadData()))) { $result = $this->deleteFolderContent($content, '', $force); } else { throw new BadRequestException('No resources given for delete.'); } } else { if (empty($this->filePath)) { // delete directory of files and the directory itself // multi-file or folder delete via post data if (!empty($content = ResourcesWrapper::unwrapResources($this->request->getPayloadData()))) { $result = $this->deleteFolderContent($content, $this->folderPath, $force); } else { $this->driver->deleteFolder($this->container, $this->folderPath, $force); $result = ['name' => basename($this->folderPath), 'path' => $this->folderPath]; } } else { // delete file from permanent storage $this->driver->deleteFile($this->container, $this->filePath); $result = ['name' => basename($this->filePath), 'path' => $this->filePath]; } } return ResourcesWrapper::cleanResources($result); }
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]; }
/** * * @return array */ public static function listServices() { return ResourcesWrapper::wrapResources(Service::available()); }