/** * Return an array of Objects * * Return an array of Object instances in this Container. * * Example: * <code> * # ... authentication code excluded (see previous examples) ... * # * $images = $conn->get_container("my photos"); * * # Grab the list of all storage objects * # * $all_objects = $images->get_objects(); * * # Grab subsets of all storage objects * # * $first_ten = $images->get_objects(10); * * # Note the use of the previous result's last object name being * # used as the 'marker' parameter to fetch the next 10 objects * # * $next_ten = $images->list_objects(10, $first_ten[count($first_ten)-1]); * * # Grab images starting with "birthday_party" and default limit/marker * # to match all photos with that prefix * # * $prefixed = $images->get_objects(0, NULL, "birthday"); * * # Assuming you have created the appropriate directory marker Objects, * # you can traverse your pseudo-hierarchical containers * # with the "path" argument. * # * $animals = $images->get_objects(0,NULL,NULL,"pictures/animals"); * $dogs = $images->get_objects(0,NULL,NULL,"pictures/animals/dogs"); * </code> * * @param int $limit <i>optional</i> only return $limit names * @param int $marker <i>optional</i> subset of names starting at $marker * @param string $prefix <i>optional</i> Objects whose names begin with $prefix * @param string $path <i>optional</i> only return results under "pathname" * @return array array of strings * @throws InvalidResponseException unexpected response */ function get_objects($limit = 0, $marker = NULL, $prefix = NULL, $path = NULL) { list($status, $reason, $obj_array) = $this->cfs_http->get_objects($this->name, $limit, $marker, $prefix, $path); #if ($status == 401 && $this->_re_auth()) { # return $this->get_objects($limit, $marker, $prefix, $path); #} if ($status < 200 || $status > 299) { throw new InvalidResponseException("Invalid response (" . $status . "): " . $this->cfs_http->get_error()); } $objects = array(); foreach ($obj_array as $obj) { $tmp = new CF_Object($this, $obj["name"], False, False); $tmp->content_type = $obj["content_type"]; $tmp->content_length = (double) $obj["bytes"]; $tmp->set_etag($obj["hash"]); $tmp->last_modified = $obj["last_modified"]; $objects[] = $tmp; } return $objects; }
/** * @see FileBackendStore::doStoreInternal() */ protected function doStoreInternal(array $params) { $status = Status::newGood(); list($dstCont, $dstRel) = $this->resolveStoragePathReal($params['dst']); if ($dstRel === null) { $status->fatal('backend-fail-invalidpath', $params['dst']); return $status; } // (a) Check the destination container and object try { unset($this->objCache[$params['dst']]); $dContObj = $this->getContainer($dstCont); if (empty($params['overwrite']) && $this->fileExists(array('src' => $params['dst'], 'latest' => 1))) { $status->fatal('backend-fail-alreadyexists', $params['dst']); return $status; } } catch (NoSuchContainerException $e) { $status->fatal('backend-fail-copy', $params['src'], $params['dst']); $this->logException($e, __METHOD__, $params); return $status; } catch (InvalidResponseException $e) { $status->fatal('backend-fail-connect', $this->name); $this->logException($e, __METHOD__, $params); return $status; } catch (Exception $e) { // some other exception? $status->fatal('backend-fail-internal', $this->name); $this->logException($e, __METHOD__, $params); return $status; } // (b) Get a SHA-1 hash of the object $sha1Hash = sha1_file($params['src']); if ($sha1Hash === false) { // source doesn't exist? $status->fatal('backend-fail-copy', $params['src'], $params['dst']); return $status; } $sha1Hash = wfBaseConvert($sha1Hash, 16, 36, 31); // (c) Actually store the object try { // Create a fresh CF_Object with no fields preloaded. // We don't want to preserve headers, metadata, and such. $obj = new CF_Object($dContObj, $dstRel, false, false); // skip HEAD // Note: metadata keys stored as [Upper case char][[Lower case char]...] $obj->metadata = array('Sha1base36' => $sha1Hash); // The MD5 here will be checked within Swift against its own MD5. $obj->set_etag(md5_file($params['src'])); // Use the same content type as StreamFile for security $obj->content_type = $this->getFileProps($params)['mime']; // Wikia cnange: use the same logic as for DB row (BAC-1199) // Actually write the object in Swift $obj->load_from_filename($params['src'], True); // calls $obj->write() } catch (BadContentTypeException $e) { $status->fatal('backend-fail-contenttype', $params['dst']); $this->logException($e, __METHOD__, $params); } catch (IOException $e) { $status->fatal('backend-fail-copy', $params['src'], $params['dst']); $this->logException($e, __METHOD__, $params); } catch (InvalidResponseException $e) { $status->fatal('backend-fail-connect', $this->name); $this->logException($e, __METHOD__, $params); } catch (Exception $e) { // some other exception? $status->fatal('backend-fail-internal', $this->name); $this->logException($e, __METHOD__, $params); } wfRunHooks('SwiftFileBackend::doStoreInternal', array($params, &$status)); return $status; }
/** * @see FileBackendStore::doStoreInternal() * @return Status */ protected function doStoreInternal(array $params) { $status = Status::newGood(); list($dstCont, $dstRel) = $this->resolveStoragePathReal($params['dst']); if ($dstRel === null) { $status->fatal('backend-fail-invalidpath', $params['dst']); return $status; } // (a) Check the destination container and object try { $dContObj = $this->getContainer($dstCont); } catch (NoSuchContainerException $e) { $status->fatal('backend-fail-copy', $params['src'], $params['dst']); return $status; } catch (CloudFilesException $e) { // some other exception? $this->handleException($e, $status, __METHOD__, $params); return $status; } // (b) Get a SHA-1 hash of the object wfSuppressWarnings(); $sha1Hash = sha1_file($params['src']); wfRestoreWarnings(); if ($sha1Hash === false) { // source doesn't exist? $status->fatal('backend-fail-copy', $params['src'], $params['dst']); return $status; } $sha1Hash = wfBaseConvert($sha1Hash, 16, 36, 31); // (c) Actually store the object try { // Create a fresh CF_Object with no fields preloaded. // We don't want to preserve headers, metadata, and such. $obj = new CF_Object($dContObj, $dstRel, false, false); // skip HEAD $obj->setMetadataValues(array('Sha1base36' => $sha1Hash)); // The MD5 here will be checked within Swift against its own MD5. $obj->set_etag(md5_file($params['src'])); // Use the same content type as StreamFile for security $obj->content_type = StreamFile::contentTypeFromPath($params['dst']); if (!strlen($obj->content_type)) { // special case $obj->content_type = 'unknown/unknown'; } // Set any other custom headers if requested if (isset($params['headers'])) { $obj->headers += $this->sanitizeHdrs($params['headers']); } if (!empty($params['async'])) { // deferred wfSuppressWarnings(); $fp = fopen($params['src'], 'rb'); wfRestoreWarnings(); if (!$fp) { $status->fatal('backend-fail-copy', $params['src'], $params['dst']); } else { $op = $obj->write_async($fp, filesize($params['src']), true); $status->value = new SwiftFileOpHandle($this, $params, 'Store', $op); $status->value->resourcesToClose[] = $fp; $status->value->affectedObjects[] = $obj; } } else { // actually write the object in Swift $obj->load_from_filename($params['src'], true); // calls $obj->write() $this->purgeCDNCache(array($obj)); } } catch (CDNNotEnabledException $e) { // CDN not enabled; nothing to see here } catch (BadContentTypeException $e) { $status->fatal('backend-fail-contenttype', $params['dst']); } catch (IOException $e) { $status->fatal('backend-fail-copy', $params['src'], $params['dst']); } catch (CloudFilesException $e) { // some other exception? $this->handleException($e, $status, __METHOD__, $params); } return $status; }
/** * Return an array of Objects. * * Return an array of Object instances in this Container. * * Example: * <code> * # ... authentication code excluded (see previous examples) ... * # * $images = $conn->get_container("my photos"); * * # Grab the list of all storage objects * # * $all_objects = $images->get_objects(); * * # Grab subsets of all storage objects * # * $first_ten = $images->get_objects(10); * * # Note the use of the previous result's last object name being * # used as the 'marker' parameter to fetch the next 10 objects * # * $next_ten = $images->list_objects(10, $first_ten[count($first_ten)-1]); * * # Grab images starting with "birthday_party" and default limit/marker * # to match all photos with that prefix * # * $prefixed = $images->get_objects(0, NULL, "birthday"); * * # Assuming you have created the appropriate directory marker Objects, * # you can traverse your pseudo-hierarchical containers * # with the "path" argument. * # * $animals = $images->get_objects(0,NULL,NULL,"pictures/animals"); * $dogs = $images->get_objects(0,NULL,NULL,"pictures/animals/dogs"); * </code> * * @param int $limit <i>optional</i> only return $limit names * @param int $marker <i>optional</i> subset of names starting at $marker * @param string $prefix <i>optional</i> Objects whose names begin with $prefix * @param string $path <i>optional</i> only return results under "pathname" * * @throws InvalidResponseException unexpected response * * @return array array of strings */ public function get_objects($limit = 0, $marker = null, $prefix = null, $path = null) { list($status, $reason, $obj_array) = $this->cfs_http->get_objects($this->name, $limit, $marker, $prefix, $path); //if ($status == 401 && $this->_re_auth()) { // return $this->get_objects($limit, $marker, $prefix, $path); //} if ($status < 200 || $status > 299) { throw new InvalidResponseException('Invalid response (' . $status . '): ' . $this->cfs_http->get_error()); } $objects = []; foreach ($obj_array as $obj) { $tmp = new CF_Object($this, $obj['name'], false, false); $tmp->content_type = $obj['content_type']; $tmp->content_length = (double) $obj['bytes']; $tmp->set_etag($obj['hash']); $tmp->last_modified = $obj['last_modified']; $objects[] = $tmp; } return $objects; }