/** * Return this user's nickname. * * The nickname will be a unique, human readable identifier for this user * with respect to this application. It will be an email address for some * users, part of the email address for some users, and the federated identity * for federated users who have not asserted an email address. * * @return string The user's nickname. */ public function getNickname() { if ($this->email != null && $this->auth_domain != null && StringUtil::endsWith($this->email, '@' . $this->auth_domain)) { $suffixLen = strlen($this->auth_domain) + 1; return substr($this->email, 0, -$suffixLen); } else { if ($this->federated_identity) { return $this->federated_identity; } else { return $this->email; } } }
/** * Retrieve more directory entries from Cloud Storage. * * @access private */ private function fillFileBuffer() { $headers = $this->getOAuthTokenHeader(parent::READ_SCOPE); if ($headers === false) { trigger_error("Unable to acquire OAuth token.", E_USER_WARNING); return false; } $query_arr = ['delimiter' => parent::DELIMITER, 'max-keys' => self::MAX_KEYS]; if (isset($this->prefix)) { $query_arr['prefix'] = $this->prefix; } if (isset($this->next_marker)) { $query_arr['marker'] = $this->next_marker; } $query_str = http_build_query($query_arr); $url = $this->createObjectUrl($this->bucket_name); $http_response = $this->makeHttpRequest(sprintf("%s?%s", $url, $query_str), "GET", $headers); if (false === $http_response) { trigger_error("Unable to connect to Google Cloud Storage Service.", E_USER_WARNING); return false; } $status_code = $http_response['status_code']; if (HttpResponse::OK != $status_code) { trigger_error($this->getErrorMessage($status_code, $http_response['body']), E_USER_WARNING); return false; } // Extract the files into the result array. $xml = simplexml_load_string($http_response['body']); if (isset($xml->NextMarker)) { $this->next_marker = (string) $xml->NextMarker; } else { $this->next_marker = null; } if (is_null($this->current_file_list)) { $this->current_file_list = []; } $prefix_len = isset($this->prefix) ? strlen($this->prefix) : 0; foreach ($xml->Contents as $content) { $key = (string) $content->Key; // Skip objects end with "_$folder$" or "/" as they exist solely for // the purpose of representing empty directories. Since we create // empty direcotires using the delimiter ("/"), they will always be // captured in the <CommonPrefixies> section. if (StringUtil::endsWith($key, parent::FOLDER_SUFFIX) || StringUtil::endsWith($key, parent::DELIMITER)) { continue; } if ($prefix_len != 0) { $key = substr($key, $prefix_len); } array_push($this->current_file_list, $key); } // All "Subdirectories" are listed as <CommonPrefixes>. See // https://developers.google.com/storage/docs/reference-methods#getbucket foreach ($xml->CommonPrefixes as $common_prefixes) { $key = (string) $common_prefixes->Prefix; if ($prefix_len != 0) { $key = substr($key, $prefix_len); } array_push($this->current_file_list, $key); } return true; }
/** * The stat function uses GET requests to the bucket to try and determine if * the object is a 'file' or a 'directory', by listing the contents of the * bucket and then matching the results against the supplied object name. * * If a file ends with "/ then Google Cloud Console will show it as a 'folder' * in the UI tool, so we consider an object that ends in "/" as a directory * as well. For backward compatibility, we also treat files with the * "_$folder$" suffix as folders. */ public function stat() { $prefix = $this->prefix; if (StringUtil::endsWith($prefix, parent::DELIMITER)) { $prefix = substr($prefix, 0, strlen($prefix) - 1); } if (isset($prefix)) { $result = $this->headObject($prefix); if ($result !== false) { $mode = parent::S_IFREG; $mtime = $result['mtime']; $size = $result['size']; } else { // Object doesn't exisit, check and see if it's a directory. do { $results = $this->listBucket($prefix); if (false === $results) { return false; } // If there are no results then we're done if (empty($results)) { return false; } // If there is an entry that contains object_name_$folder$ or // object_name/ then we have a 'directory'. $object_name_folder = $prefix . parent::FOLDER_SUFFIX; $object_name_delimiter = $prefix . parent::DELIMITER; foreach ($results as $result) { if ($result['name'] === $object_name_folder || $result['name'] === $object_name_delimiter) { $mode = parent::S_IFDIR; break; } } } while (!isset($mode) && isset($this->next_marker)); } } else { // We are now just checking that the bucket exists, as there was no // object prefix supplied $results = $this->listBucket(); if ($results !== false) { $mode = parent::S_IFDIR; } else { return false; } } // If mode is not set, then there was no object that matched the criteria. if (!isset($mode)) { return false; } // If the app could stat the file, then it must be readable. As different // PHP internal APIs check the access mode, we'll set them all to readable. $mode |= parent::S_IRUSR | parent::S_IRGRP | parent::S_IROTH; if ($this->isBucketWritable($this->bucket_name)) { $mode |= parent::S_IWUSR | parent::S_IWGRP | parent::S_IWOTH; } $stat_args["mode"] = $mode; if (isset($mtime)) { $unix_time = strtotime($mtime); if ($unix_time !== false) { $stat_args["mtime"] = $unix_time; } } if (isset($size)) { $stat_args["size"] = intval($size); } return $this->createStatArray($stat_args); }