Beispiel #1
0
 /**
  * @param array             $resources
  * @param boolean           $as_list
  * @param string|array|null $identifier
  * @param string|array|null $fields
  * @param boolean           $force_wrap
  *
  * @return array
  */
 public static function cleanResources($resources, $as_list = false, $identifier = null, $fields = null, $force_wrap = false)
 {
     // avoid single resources or already wrapped resources
     if (ArrayUtils::isArrayNumeric($resources)) {
         // may already be a simple list
         if (is_array(ArrayUtils::get($resources, 0))) {
             if (is_string($identifier)) {
                 $identifier = explode(',', $identifier);
             } elseif (!is_array($identifier)) {
                 $identifier = [];
             }
             $identifier = array_values($identifier);
             if ($as_list) {
                 if (1 == count($identifier)) {
                     $resources = array_column($resources, $identifier[0]);
                 } else {
                     foreach ($resources as &$resource) {
                         $out = '';
                         foreach ($identifier as $idField) {
                             if (!empty($out)) {
                                 $out .= ',';
                             }
                             $out .= ArrayUtils::get($resource, $idField, '');
                         }
                         $resource = '(' . $out . ')';
                     }
                 }
             } elseif (empty($fields)) {
                 if (is_array($identifier) && !empty($identifier)) {
                     $identifier = array_flip($identifier);
                     foreach ($resources as &$resource) {
                         $resource = array_intersect_key($resource, $identifier);
                     }
                 }
             } elseif (ApiOptions::FIELDS_ALL !== $fields) {
                 if (is_string($fields)) {
                     $fields = explode(',', $fields);
                 } elseif (!is_array($fields)) {
                     $fields = [];
                 }
                 $fields = array_flip(array_values($fields));
                 foreach ($resources as &$resource) {
                     $resource = array_intersect_key($resource, $fields);
                 }
             }
         }
         return static::wrapResources($resources, $force_wrap);
     }
     return $force_wrap ? static::wrapResources($resources, true) : $resources;
 }
Beispiel #2
0
 /**
  * {@inheritdoc}
  */
 protected function getPayloadData($key = null, $default = null)
 {
     $payload = parent::getPayloadData();
     if (null !== $key && !empty($payload[$key])) {
         return $payload[$key];
     }
     //        $alwaysWrap = \Config::get('df.always_wrap_resources', false);
     $wrapper = ResourcesWrapper::getWrapper();
     if (!empty($this->resource) && !empty($payload)) {
         // single records passed in which don't use the record wrapper, so wrap it
         $payload = [$wrapper => [$payload]];
     } elseif (ArrayUtils::isArrayNumeric($payload)) {
         // import from csv, etc doesn't include a wrapper, so wrap it
         $payload = [$wrapper => $payload];
     }
     if (empty($key)) {
         $key = $wrapper;
     }
     return ArrayUtils::get($payload, $key);
 }
Beispiel #3
0
 /**
  * @param mixed  $data
  * @param string $root
  * @param int    $level
  * @param bool   $format
  *
  * @return string
  */
 protected static function arrayToXmlInternal($data, $root = null, $level = 1, $format = true)
 {
     $xml = null;
     if (ArrayUtils::isArrayNumeric($data)) {
         foreach ($data as $value) {
             $xml .= self::arrayToXmlInternal($value, $root, $level, $format);
         }
     } else {
         if (ArrayUtils::isArrayAssociative($data)) {
             if (!empty($root)) {
                 if ($format) {
                     $xml .= str_repeat("\t", $level - 1);
                 }
                 $xml .= "<{$root}>";
                 if ($format) {
                     $xml .= "\n";
                 }
             }
             foreach ($data as $key => $value) {
                 $xml .= self::arrayToXmlInternal($value, $key, $level + 1, $format);
             }
             if (!empty($root)) {
                 if ($format) {
                     $xml .= str_repeat("\t", $level - 1);
                 }
                 $xml .= "</{$root}>";
                 if ($format) {
                     $xml .= "\n";
                 }
             }
         } else {
             if (is_array($data)) {
                 // empty array
             } else {
                 // not an array
                 if (!empty($root)) {
                     if ($format) {
                         $xml .= str_repeat("\t", $level - 1);
                     }
                     $xml .= "<{$root}>";
                     if (!is_null($data)) {
                         if (is_bool($data)) {
                             $xml .= $data ? 'true' : 'false';
                         } else {
                             if (is_int($data) || is_float($data)) {
                                 $xml .= $data;
                             } else {
                                 if (is_string($data)) {
                                     $htmlValue = htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
                                     $xml .= $htmlValue;
                                 }
                             }
                         }
                     }
                     $xml .= "</{$root}>";
                     if ($format) {
                         $xml .= "\n";
                     }
                 }
             }
         }
     }
     return $xml;
 }
Beispiel #4
0
 /**
  * If fields is not '*' (all) then remove the empty 'config' property.
  *
  * @param array $response
  * @param mixed $fields
  *
  * @return array
  */
 protected static function cleanResult(array $response, $fields)
 {
     if (!is_array($fields)) {
         $fields = explode(',', $fields);
     }
     //config is only available when both id and type is present. Therefore only show config if id and type is there.
     if (ArrayUtils::get($fields, 0) !== '*' && (!in_array('type', $fields) || !in_array('id', $fields))) {
         $result = [];
         if (ArrayUtils::isArrayNumeric($response)) {
             foreach ($response as $r) {
                 if (isset($r['config'])) {
                     unset($r['config']);
                 }
                 $result[] = $r;
             }
         } else {
             foreach ($response as $k => $v) {
                 if ('config' === $k) {
                     unset($response[$k]);
                 }
             }
             $result = $response;
         }
         return $result;
     }
     return $response;
 }
Beispiel #5
0
 /**
  * Fixes supplied records to always set is_set_admin flag to true.
  * Encrypts passwords if it is supplied.
  *
  * @param array $records
  *
  * @return array
  */
 protected static function fixRecords(array $records)
 {
     if (ArrayUtils::isArrayNumeric($records)) {
         foreach ($records as $key => $record) {
             ArrayUtils::set($record, 'is_sys_admin', 1);
             $records[$key] = $record;
         }
     } else {
         ArrayUtils::set($records, 'is_sys_admin', 1);
     }
     return $records;
 }
Beispiel #6
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;
 }
Beispiel #7
0
 /**
  * @param array $data
  * @param bool  $extract
  * @param bool  $clean
  * @param bool  $checkExist
  *
  * @return array
  */
 protected function handleFolderContentFromData($data, $extract = false, $clean = false, $checkExist = false)
 {
     $out = [];
     if (!empty($data) && ArrayUtils::isArrayNumeric($data)) {
         foreach ($data as $key => $resource) {
             switch (ArrayUtils::get($resource, 'type')) {
                 case 'folder':
                     $name = ArrayUtils::get($resource, 'name', '');
                     $srcPath = ArrayUtils::get($resource, 'source_path');
                     if (!empty($srcPath)) {
                         $srcContainer = ArrayUtils::get($resource, 'source_container', $this->container);
                         // copy or move
                         if (empty($name)) {
                             $name = FileUtilities::getNameFromPath($srcPath);
                         }
                         $fullPathName = $this->folderPath . $name . '/';
                         $out[$key] = ['name' => $name, 'path' => $fullPathName, 'type' => 'folder'];
                         try {
                             $this->driver->copyFolder($this->container, $fullPathName, $srcContainer, $srcPath, true);
                             $deleteSource = ArrayUtils::getBool($resource, 'delete_source');
                             if ($deleteSource) {
                                 $this->driver->deleteFolder($this->container, $srcPath, true);
                             }
                         } catch (\Exception $ex) {
                             $out[$key]['error'] = ['message' => $ex->getMessage()];
                         }
                     } else {
                         $fullPathName = $this->folderPath . $name . '/';
                         $content = ArrayUtils::get($resource, 'content', '');
                         $isBase64 = ArrayUtils::getBool($resource, 'is_base64');
                         if ($isBase64) {
                             $content = base64_decode($content);
                         }
                         $out[$key] = ['name' => $name, 'path' => $fullPathName, 'type' => 'folder'];
                         try {
                             $this->driver->createFolder($this->container, $fullPathName, $content);
                         } catch (\Exception $ex) {
                             $out[$key]['error'] = ['message' => $ex->getMessage()];
                         }
                     }
                     break;
                 case 'file':
                     $name = ArrayUtils::get($resource, 'name', '');
                     $srcPath = ArrayUtils::get($resource, 'source_path');
                     if (!empty($srcPath)) {
                         // copy or move
                         $srcContainer = ArrayUtils::get($resource, 'source_container', $this->container);
                         if (empty($name)) {
                             $name = FileUtilities::getNameFromPath($srcPath);
                         }
                         $fullPathName = $this->folderPath . $name;
                         $out[$key] = ['name' => $name, 'path' => $fullPathName, 'type' => 'file'];
                         try {
                             $this->driver->copyFile($this->container, $fullPathName, $srcContainer, $srcPath, true);
                             $deleteSource = ArrayUtils::getBool($resource, 'delete_source');
                             if ($deleteSource) {
                                 $this->driver->deleteFile($this->container, $srcPath);
                             }
                         } catch (\Exception $ex) {
                             $out[$key]['error'] = ['message' => $ex->getMessage()];
                         }
                     } elseif (isset($resource['content'])) {
                         $fullPathName = $this->folderPath . $name;
                         $out[$key] = ['name' => $name, 'path' => $fullPathName, 'type' => 'file'];
                         $content = ArrayUtils::get($resource, 'content', '');
                         $isBase64 = ArrayUtils::getBool($resource, 'is_base64');
                         if ($isBase64) {
                             $content = base64_decode($content);
                         }
                         try {
                             $this->driver->writeFile($this->container, $fullPathName, $content);
                         } catch (\Exception $ex) {
                             $out[$key]['error'] = ['message' => $ex->getMessage()];
                         }
                     }
                     break;
             }
         }
     }
     return $out;
 }
 /**
  *
  *
  * IMPORTANT: The representation of the data will be placed back into the original location/position in the $record
  * from which it was "normalized". This means that any client-side handlers will have to deal with the bogus
  * determinations. Just be aware.
  *
  * Below is a side-by-side comparison of record data as shown sent by or returned to the caller, and sent to an
  * event handler.
  *
  *  REST API v1.0                           Event Representation
  *  -------------                           --------------------
  *  Single row...                           Add a 'record' key and make it look like a multi-row
  *
  *      array(                              array(
  *          'id' => 1,                          'record' => array(
  *      )                                           0 => array( 'id' => 1, ),
  *                                              ),
  *                                          ),
  *
  * Multi-row...                             Stays the same...or gets wrapped by adding a 'record' key
  *
  *      array(                              array(
  *          'record' => array(                  'record' =>  array(
  *              0 => array( 'id' => 1 ),            0 => array( 'id' => 1 ),
  *              1 => array( 'id' => 2 ),            1 => array( 'id' => 2 ),
  *              2 => array( 'id' => 3 ),            2 => array( 'id' => 3 ),
  *          ),                                  ),
  *      )                                   )
  *
  * or...
  *
  *      array(                              array(
  *          0 => array( 'id' => 1 ),            'record' =>  array(
  *          1 => array( 'id' => 2 ),                0 => array( 'id' => 1 ),
  *          2 => array( 'id' => 3 ),                1 => array( 'id' => 2 ),
  *      ),                                          2 => array( 'id' => 3 ),
  *                                              ),
  *                                          )
  */
 protected function detectRequestMembers()
 {
     $wrapper = ResourcesWrapper::getWrapper();
     // override - don't call parent class here
     $this->payload = $this->getPayloadData();
     if (!empty($this->resource)) {
         if (!empty($this->resourceId)) {
             if (!empty($this->payload)) {
                 // fix wrapper on posted single record
                 if (!isset($this->payload[$wrapper])) {
                     // single records don't use the record wrapper, so wrap it
                     $this->payload = [$wrapper => [$this->payload]];
                 }
             }
         } elseif (ArrayUtils::isArrayNumeric($this->payload)) {
             // import from csv, etc doesn't include a wrapper, so wrap it
             $this->payload = [$wrapper => $this->payload];
         } else {
             if (!empty($this->payload)) {
                 switch ($this->request->getMethod()) {
                     case Verbs::POST:
                     case Verbs::PUT:
                     case Verbs::PATCH:
                     case Verbs::MERGE:
                         // fix wrapper on posted single record
                         if (!isset($this->payload[$wrapper])) {
                             // stuff it back in for event
                             $this->payload[$wrapper] = [$this->payload];
                         }
                         break;
                 }
             }
         }
         $this->options = $this->request->getParameters();
         // merge in possible payload options
         $optionNames = [ApiOptions::LIMIT, ApiOptions::OFFSET, ApiOptions::ORDER, ApiOptions::GROUP, ApiOptions::FIELDS, ApiOptions::IDS, ApiOptions::FILTER, ApiOptions::PARAMS, ApiOptions::CONTINUES, ApiOptions::ROLLBACK];
         foreach ($optionNames as $key => $value) {
             if (!array_key_exists($value, $this->options)) {
                 if (array_key_exists($value, $this->payload)) {
                     $this->options[$value] = $this->payload[$value];
                 } elseif (!empty($otherNames = ApiOptions::getAliases($value))) {
                     foreach ($otherNames as $other) {
                         if (!array_key_exists($other, $this->options)) {
                             if (array_key_exists($other, $this->payload)) {
                                 $this->options[$value] = $this->payload[$other];
                             }
                         } else {
                             $this->options[$value] = $this->options[$other];
                         }
                     }
                 }
             }
         }
         // set defaults if not present
         if (Verbs::GET == $this->request->getMethod()) {
             // default for GET should be "return all fields"
             if (!array_key_exists(ApiOptions::FIELDS, $this->options)) {
                 $this->options[ApiOptions::FIELDS] = '*';
             }
         }
         // Add server side filtering properties
         $resource = $this->name . '/' . $this->resource;
         if (null != ($ssFilters = Session::getServiceFilters($this->getRequestedAction(), $this->parent->name, $resource))) {
             $this->options['ss_filters'] = $ssFilters;
         }
     }
 }
Beispiel #9
0
 /**
  * @param $response
  *
  * @return mixed
  * @throws \Exception
  */
 protected function handleInvitation($response)
 {
     try {
         $sendInvite = $this->request->getParameterAsBool('send_invite');
         switch ($this->action) {
             case Verbs::POST:
             case Verbs::PUT:
             case Verbs::PATCH:
             case Verbs::MERGE:
                 if ($sendInvite) {
                     if ($response instanceof ServiceResponseInterface) {
                         $response = $response->getContent();
                     }
                     if (is_array($response)) {
                         $records = ArrayUtils::get($response, ResourcesWrapper::DEFAULT_WRAPPER);
                         if (ArrayUtils::isArrayNumeric($records)) {
                             $passed = true;
                             foreach ($records as $record) {
                                 $id = ArrayUtils::get($record, 'id');
                                 try {
                                     static::sendInvite($id, $this->action === Verbs::POST);
                                 } catch (\Exception $e) {
                                     if (count($records) === 1) {
                                         throw $e;
                                     } else {
                                         $passed = false;
                                         Log::error('Error processing invitation for user id ' . $id . ': ' . $e->getMessage());
                                     }
                                 }
                             }
                             if (!$passed) {
                                 throw new InternalServerErrorException('Not all users were created successfully. Check log for more details.');
                             }
                         } else {
                             $id = ArrayUtils::get($response, 'id');
                             if (empty($id)) {
                                 throw new InternalServerErrorException('Invalid user id in response.');
                             }
                             static::sendInvite($id, $this->action === Verbs::POST);
                         }
                     }
                 }
                 break;
         }
         return $response;
     } catch (\Exception $ex) {
         throw $ex;
     }
 }