diff --git a/src/Audit/Adapter.php b/src/Audit/Adapter.php index 0c66b4553..5aa7cc201 100644 --- a/src/Audit/Adapter.php +++ b/src/Audit/Adapter.php @@ -9,17 +9,19 @@ abstract class Adapter protected $namespace = ''; /** - * Set Namespace + * Set Namespace. * * Set namespace to divide different scope of data sets * * @param $namespace + * * @throws Exception + * * @return bool */ public function setNamespace($namespace) { - if(empty($namespace)) { + if (empty($namespace)) { throw new Exception('Missing namespace'); } @@ -29,16 +31,17 @@ abstract class Adapter } /** - * Get Namespace + * Get Namespace. * * Get namespace of current set scope * * @throws Exception + * * @return string */ public function getNamespace() { - if(empty($this->namespace)) { + if (empty($this->namespace)) { throw new Exception('Missing namespace'); } @@ -46,41 +49,44 @@ abstract class Adapter } /** - * Log + * Log. * * Add specific event log * - * @param int $userId - * @param int $userType + * @param int $userId + * @param int $userType * @param string $event * @param string $resource * @param string $userAgent * @param string $ip * @param string $location - * @param array $data + * @param array $data + * * @return */ abstract public function log($userId, $userType, $event, $resource, $userAgent, $ip, $location, $data); /** - * Get All Logs By User + * Get All Logs By User. * * Get all user logs * * @param int $userId * @param int $userType + * * @return mixed */ abstract public function getLogsByUser($userId, $userType); /** - * Get All Logs By User and Actions + * Get All Logs By User and Actions. * * Get all user logs by given action names * - * @param int $userId - * @param int $userType + * @param int $userId + * @param int $userType * @param array $actions + * * @return mixed */ abstract public function getLogsByUserAndActions($userId, $userType, array $actions); diff --git a/src/Audit/Adapter/MySQL.php b/src/Audit/Adapter/MySQL.php index 556335459..297807795 100644 --- a/src/Audit/Adapter/MySQL.php +++ b/src/Audit/Adapter/MySQL.php @@ -21,25 +21,27 @@ class MySQL extends Adapter } /** - * Log + * Log. * * Add specific event log * - * @param int $userId - * @param int $userType + * @param int $userId + * @param int $userType * @param string $event * @param string $resource * @param string $userAgent * @param string $ip * @param string $location - * @param array $data + * @param array $data + * * @return bool + * * @throws \Exception */ public function log($userId, $userType, $event, $resource, $userAgent, $ip, $location, $data) { - $st = $this->getPDO()->prepare('INSERT INTO `' . $this->getNamespace() . '.audit.audit` - SET userId = :userId, userType = :userType, event= :event, resource= :resource, userAgent = :userAgent, ip = :ip, location = :location, time = "' . date('Y-m-d H:i:s') . '", data = :data + $st = $this->getPDO()->prepare('INSERT INTO `'.$this->getNamespace().'.audit.audit` + SET userId = :userId, userType = :userType, event= :event, resource= :resource, userAgent = :userAgent, ip = :ip, location = :location, time = "'.date('Y-m-d H:i:s').'", data = :data '); $data = mb_strcut(json_encode($data), 0, 64000, 'UTF-8'); // Limit data to MySQL 64kb limit @@ -61,7 +63,7 @@ class MySQL extends Adapter public function getLogsByUser($userId, $userType) { $st = $this->getPDO()->prepare('SELECT * - FROM `' . $this->getNamespace() . '.audit.audit` + FROM `'.$this->getNamespace().'.audit.audit` WHERE userId = :userId AND userType = :userType ORDER BY `time` DESC LIMIT 10 @@ -79,14 +81,15 @@ class MySQL extends Adapter { $query = []; - foreach ($actions as $k => $id) - $query[] = ':action_' . $k; + foreach ($actions as $k => $id) { + $query[] = ':action_'.$k; + } $query = implode(',', $query); $st = $this->getPDO()->prepare('SELECT * - FROM `' . $this->getNamespace() . '.audit.audit` - WHERE `event` IN (' . $query . ') + FROM `'.$this->getNamespace().'.audit.audit` + WHERE `event` IN ('.$query.') AND userId = :userId AND userType = :userType ORDER BY `time` DESC LIMIT 10 @@ -95,8 +98,9 @@ class MySQL extends Adapter $st->bindValue(':userId', $userId, PDO::PARAM_STR); $st->bindValue(':userType', $userType, PDO::PARAM_INT); - foreach ($actions as $k => $id) - $st->bindValue(':action_' . $k, $id); + foreach ($actions as $k => $id) { + $st->bindValue(':action_'.$k, $id); + } $st->execute(); diff --git a/src/Audit/Audit.php b/src/Audit/Audit.php index ad04ab47b..2b6aac7f1 100644 --- a/src/Audit/Audit.php +++ b/src/Audit/Audit.php @@ -36,30 +36,31 @@ class Audit /** * @param Adapter $adapter - * @param int $userId - * @param int $userType - * @param string $userAgent - * @param string $ip - * @param string $location + * @param int $userId + * @param int $userType + * @param string $userAgent + * @param string $ip + * @param string $location */ public function __construct(Adapter $adapter, $userId, $userType, $userAgent, $ip, $location) { - $this->adapter = $adapter; - $this->userId = $userId; - $this->userType = $userType; - $this->userAgent = $userAgent; - $this->ip = $ip; - $this->location = $location; + $this->adapter = $adapter; + $this->userId = $userId; + $this->userType = $userType; + $this->userAgent = $userAgent; + $this->ip = $ip; + $this->location = $location; } /** - * Log + * Log. * * Add specific event log * * @param string $event * @param string $resource - * @param array $data + * @param array $data + * * @return mixed */ public function log($event, $resource = '', array $data = []) @@ -68,12 +69,13 @@ class Audit } /** - * Get All Logs By User and Actions + * Get All Logs By User and Actions. * * Get all user logs logs by given action names * * @param int $userId * @param int $userType + * * @return mixed */ public function getLogsByUser($userId, $userType) @@ -82,13 +84,14 @@ class Audit } /** - * Get All Logs By User and Actions + * Get All Logs By User and Actions. * * Get all user logs logs by given action names * - * @param int $userId - * @param int $userType + * @param int $userId + * @param int $userType * @param array $actions + * * @return mixed */ public function getLogsByUserAndActions($userId, $userType, array $actions) diff --git a/src/Auth/Auth.php b/src/Auth/Auth.php index c94b93f00..736f7e79a 100644 --- a/src/Auth/Auth.php +++ b/src/Auth/Auth.php @@ -7,93 +7,95 @@ use Database\Document; class Auth { /** - * User Gender + * User Gender. */ - const USER_GENDER_TYPE_NOT_SET = 0; - const USER_GENDER_TYPE_MALE = 1; - const USER_GENDER_TYPE_FEMALE = 2; - const USER_GENDER_TYPE_OTHER = 3; + const USER_GENDER_TYPE_NOT_SET = 0; + const USER_GENDER_TYPE_MALE = 1; + const USER_GENDER_TYPE_FEMALE = 2; + const USER_GENDER_TYPE_OTHER = 3; /** - * User Status + * User Status. */ - const USER_STATUS_UNACTIVATED = 0; - const USER_STATUS_ACTIVATED = 1; - const USER_STATUS_BLOCKED = 2; + const USER_STATUS_UNACTIVATED = 0; + const USER_STATUS_ACTIVATED = 1; + const USER_STATUS_BLOCKED = 2; /** - * User Types + * User Types. */ - const USER_TYPE_USER = 0; - const USER_TYPE_PARENT = 1; - const USER_TYPE_APP = 2; + const USER_TYPE_USER = 0; + const USER_TYPE_PARENT = 1; + const USER_TYPE_APP = 2; /** - * User Roles + * User Roles. */ - const USER_ROLE_GUEST = 0; - const USER_ROLE_MEMBER = 1; - const USER_ROLE_ADMIN = 2; - const USER_ROLE_DEVELOPER = 3; - const USER_ROLE_OWNER = 4; - const USER_ROLE_APP = 5; - const USER_ROLE_SYSTEM = 6; - const USER_ROLE_ALL = '*'; + const USER_ROLE_GUEST = 0; + const USER_ROLE_MEMBER = 1; + const USER_ROLE_ADMIN = 2; + const USER_ROLE_DEVELOPER = 3; + const USER_ROLE_OWNER = 4; + const USER_ROLE_APP = 5; + const USER_ROLE_SYSTEM = 6; + const USER_ROLE_ALL = '*'; /** - * Token Types + * Token Types. */ - const TOKEN_TYPE_LOGIN = 1; - const TOKEN_TYPE_CONFIRM = 2; - const TOKEN_TYPE_RECOVERY = 3; - const TOKEN_TYPE_INVITE = 4; + const TOKEN_TYPE_LOGIN = 1; + const TOKEN_TYPE_CONFIRM = 2; + const TOKEN_TYPE_RECOVERY = 3; + const TOKEN_TYPE_INVITE = 4; /** - * Token Expiration times + * Token Expiration times. */ - const TOKEN_EXPIRATION_LOGIN_LONG = 31536000; /* 1 year */ - const TOKEN_EXPIRATION_LOGIN_SHORT = 3600; /* 1 hour */ - const TOKEN_EXPIRATION_RECOVERY = 3600; /* 1 hour */ - const TOKEN_EXPIRATION_CONFIRM = 3600 * 24 * 7; /* 7 days */ + const TOKEN_EXPIRATION_LOGIN_LONG = 31536000; /* 1 year */ + const TOKEN_EXPIRATION_LOGIN_SHORT = 3600; /* 1 hour */ + const TOKEN_EXPIRATION_RECOVERY = 3600; /* 1 hour */ + const TOKEN_EXPIRATION_CONFIRM = 3600 * 24 * 7; /* 7 days */ /** * @var string */ - static public $cookieName = 'a-session'; + public static $cookieName = 'a-session'; /** - * User Unique ID + * User Unique ID. * * @var int */ - static public $unique = 0; + public static $unique = 0; /** - * User Secret Key + * User Secret Key. * * @var string */ - static public $secret = ''; + public static $secret = ''; /** - * Set Cookie Name + * Set Cookie Name. * * @param $string + * * @return string */ - static public function setCookieName($string) + public static function setCookieName($string) { return self::$cookieName = $string; } /** - * Encode Session + * Encode Session. * - * @param int $id + * @param int $id * @param string $secret + * * @return string */ - static public function encodeSession($id, $secret) + public static function encodeSession($id, $secret) { return base64_encode(json_encode([ 'id' => $id, @@ -102,18 +104,20 @@ class Auth } /** - * Decode Session + * Decode Session. * * @param string $session + * * @return array + * * @throws \Exception */ - static public function decodeSession($session) + public static function decodeSession($session) { $session = json_decode(base64_decode($session), true); - $default = ['id' => null, 'secret' => '',]; + $default = ['id' => null, 'secret' => '']; - if(!is_array($session)) { + if (!is_array($session)) { return $default; } @@ -121,83 +125,91 @@ class Auth } /** - * Encode + * Encode. * * One-way encryption * * @param $string + * * @return string */ - static public function hash($string) + public static function hash($string) { - return hash('sha256',$string); + return hash('sha256', $string); } /** - * Password Hash + * Password Hash. * * One way string hashing for user passwords * * @param $string + * * @return bool|string */ - static public function passwordHash($string) + public static function passwordHash($string) { return password_hash($string, PASSWORD_BCRYPT, array('cost' => 8)); } /** - * Password verify + * Password verify. * * @param $plain * @param $hash + * * @return bool */ - static public function passwordVerify($plain, $hash) + public static function passwordVerify($plain, $hash) { return password_verify($plain, $hash); } /** - * Password Generator + * Password Generator. * * Generate random password string * * @param int $length + * * @return string + * * @throws \Exception */ - static public function passwordGenerator(int $length = 20):string + public static function passwordGenerator(int $length = 20):string { return bin2hex(random_bytes($length)); } /** - * Token Generator + * Token Generator. * * Generate random password string * * @param int $length + * * @return string + * * @throws \Exception */ - static public function tokenGenerator(int $length = 128):string + public static function tokenGenerator(int $length = 128):string { return bin2hex(random_bytes($length)); } /** - * Verify token and check that its not expired + * Verify token and check that its not expired. * - * @param array $tokens - * @param int $type + * @param array $tokens + * @param int $type * @param string $secret + * * @return bool|int */ - static public function tokenVerify(array $tokens, int $type, string $secret) + public static function tokenVerify(array $tokens, int $type, string $secret) { foreach ($tokens as $token) { /* @var $token Document */ - if(isset($token['type']) && + if (isset($token['type']) && isset($token['secret']) && isset($token['expire']) && $token['type'] == $type && @@ -209,4 +221,4 @@ class Auth return false; } -} \ No newline at end of file +} diff --git a/src/Auth/OAuth.php b/src/Auth/OAuth.php index b2c1341d1..ae9539fa4 100644 --- a/src/Auth/OAuth.php +++ b/src/Auth/OAuth.php @@ -30,14 +30,14 @@ abstract class OAuth * @param string $appId * @param string $appSecret * @param string $callback - * @param array $state + * @param array $state */ public function __construct(string $appId, string $appSecret, string $callback, $state = []) { - $this->appID = $appId; - $this->appSecret = $appSecret; - $this->callback = $callback; - $this->state = $state; + $this->appID = $appId; + $this->appSecret = $appSecret; + $this->callback = $callback; + $this->state = $state; } /** @@ -52,24 +52,28 @@ abstract class OAuth /** * @param string $code + * * @return string */ abstract public function getAccessToken(string $code):string; /** * @param $accessToken + * * @return string */ abstract public function getUserID(string $accessToken):string; /** * @param $accessToken + * * @return string */ abstract public function getUserEmail(string $accessToken):string; /** * @param $accessToken + * * @return string */ abstract public function getUserName(string $accessToken):string; @@ -77,13 +81,14 @@ abstract class OAuth /** * @param string $method * @param string $url - * @param array $headers + * @param array $headers * @param string $payload + * * @return string */ protected function request(string $method, string $url = '', array $headers = [], string $payload = ''):string { - $ch = curl_init($url); + $ch = curl_init($url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); curl_setopt($ch, CURLOPT_HEADER, 0); @@ -91,7 +96,7 @@ abstract class OAuth curl_setopt($ch, CURLOPT_USERAGENT, 'Console_OAuth_Agent'); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - if(!empty($payload)) { + if (!empty($payload)) { curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); } @@ -102,4 +107,4 @@ abstract class OAuth return $response; } -} \ No newline at end of file +} diff --git a/src/Auth/OAuth/Facebook.php b/src/Auth/OAuth/Facebook.php index 5002a02dc..1c1bbfd60 100644 --- a/src/Auth/OAuth/Facebook.php +++ b/src/Auth/OAuth/Facebook.php @@ -29,25 +29,26 @@ class Facebook extends OAuth */ public function getLoginURL():string { - return 'https://www.facebook.com/' . $this->version . '/dialog/oauth?client_id=' . urlencode($this->appID) . '&redirect_uri=' . urlencode($this->callback) . '&scope=email&state=' . urlencode(json_encode($this->state)); + return 'https://www.facebook.com/'.$this->version.'/dialog/oauth?client_id='.urlencode($this->appID).'&redirect_uri='.urlencode($this->callback).'&scope=email&state='.urlencode(json_encode($this->state)); } /** * @param string $code + * * @return string */ public function getAccessToken(string $code):string { - $accessToken = $this->request('GET', 'https://graph.facebook.com/' . $this->version . '/oauth/access_token?' . - 'client_id=' . urlencode($this->appID) . - '&redirect_uri=' . urlencode($this->callback) . - '&client_secret=' . urlencode($this->appSecret) . - '&code=' . urlencode($code) + $accessToken = $this->request('GET', 'https://graph.facebook.com/'.$this->version.'/oauth/access_token?'. + 'client_id='.urlencode($this->appID). + '&redirect_uri='.urlencode($this->callback). + '&client_secret='.urlencode($this->appSecret). + '&code='.urlencode($code) ); $accessToken = json_decode($accessToken, true); // - if(isset($accessToken['access_token'])) { + if (isset($accessToken['access_token'])) { return $accessToken['access_token']; } @@ -56,13 +57,14 @@ class Facebook extends OAuth /** * @param string $accessToken + * * @return string */ public function getUserID(string $accessToken):string { $user = $this->getUser($accessToken); - if(isset($user['id'])) { + if (isset($user['id'])) { return $user['id']; } @@ -71,13 +73,14 @@ class Facebook extends OAuth /** * @param string $accessToken + * * @return string */ public function getUserEmail(string $accessToken):string { $user = $this->getUser($accessToken); - if(isset($user['email'])) { + if (isset($user['email'])) { return $user['email']; } @@ -86,13 +89,14 @@ class Facebook extends OAuth /** * @param string $accessToken + * * @return string */ public function getUserName(string $accessToken):string { $user = $this->getUser($accessToken); - if(isset($user['name'])) { + if (isset($user['name'])) { return $user['name']; } @@ -101,16 +105,17 @@ class Facebook extends OAuth /** * @param string $accessToken + * * @return array */ protected function getUser(string $accessToken):array { - if(empty($this->user)) { - $user = $this->request('GET', 'https://graph.facebook.com/' . $this->version . '/me?fields=email,name&access_token=' . urlencode($accessToken)); + if (empty($this->user)) { + $user = $this->request('GET', 'https://graph.facebook.com/'.$this->version.'/me?fields=email,name&access_token='.urlencode($accessToken)); $this->user = json_decode($user, true); } return $this->user; } -} \ No newline at end of file +} diff --git a/src/Auth/OAuth/GitHub.php b/src/Auth/OAuth/GitHub.php index 37b608d17..bcae83c53 100644 --- a/src/Auth/OAuth/GitHub.php +++ b/src/Auth/OAuth/GitHub.php @@ -24,27 +24,28 @@ class Github extends OAuth */ public function getLoginURL():string { - return 'https://github.com/login/oauth/authorize?client_id=' . urlencode($this->appID) . '&redirect_uri=' . urlencode($this->callback) . '&scope=user:email&state=' . urlencode(json_encode($this->state)); + return 'https://github.com/login/oauth/authorize?client_id='.urlencode($this->appID).'&redirect_uri='.urlencode($this->callback).'&scope=user:email&state='.urlencode(json_encode($this->state)); } /** * @param string $code + * * @return string */ public function getAccessToken(string $code):string { $accessToken = $this->request('POST', 'https://github.com/login/oauth/access_token', [], - 'client_id=' . urlencode($this->appID) . - '&redirect_uri=' . urlencode($this->callback) . - '&client_secret=' . urlencode($this->appSecret) . - '&code=' . urlencode($code) + 'client_id='.urlencode($this->appID). + '&redirect_uri='.urlencode($this->callback). + '&client_secret='.urlencode($this->appSecret). + '&code='.urlencode($code) ); $output = []; parse_str($accessToken, $output); - if(isset($output['access_token'])) { + if (isset($output['access_token'])) { return $output['access_token']; } @@ -53,13 +54,14 @@ class Github extends OAuth /** * @param $accessToken + * * @return string */ public function getUserID(string $accessToken):string { $user = $this->getUser($accessToken); - if(isset($user['id'])) { + if (isset($user['id'])) { return $user['id']; } @@ -68,14 +70,15 @@ class Github extends OAuth /** * @param $accessToken + * * @return string */ public function getUserEmail(string $accessToken):string { - $emails = json_decode($this->request('GET', 'https://api.github.com/user/emails', ['Authorization: token ' . urlencode($accessToken)]), true); + $emails = json_decode($this->request('GET', 'https://api.github.com/user/emails', ['Authorization: token '.urlencode($accessToken)]), true); - foreach($emails as $email) { - if($email['primary'] && $email['verified']) { + foreach ($emails as $email) { + if ($email['primary'] && $email['verified']) { return $email['email']; } } @@ -85,13 +88,14 @@ class Github extends OAuth /** * @param $accessToken + * * @return string */ public function getUserName(string $accessToken):string { $user = $this->getUser($accessToken); - if(isset($user['name'])) { + if (isset($user['name'])) { return $user['name']; } @@ -100,14 +104,15 @@ class Github extends OAuth /** * @param string $accessToken + * * @return array */ protected function getUser(string $accessToken) { - if(empty($this->user)) { - $this->user = json_decode($this->request('GET', 'https://api.github.com/user', ['Authorization: token ' . urlencode($accessToken)]), true); + if (empty($this->user)) { + $this->user = json_decode($this->request('GET', 'https://api.github.com/user', ['Authorization: token '.urlencode($accessToken)]), true); } return $this->user; } -} \ No newline at end of file +} diff --git a/src/Auth/OAuth/LinkedIn.php b/src/Auth/OAuth/LinkedIn.php index 9bfeba58f..638071efc 100644 --- a/src/Auth/OAuth/LinkedIn.php +++ b/src/Auth/OAuth/LinkedIn.php @@ -20,7 +20,7 @@ class LinkedIn extends OAuth ]; /** - * Documentation + * Documentation. * * OAuth: * https://developer.linkedin.com/docs/oauth2 @@ -30,7 +30,6 @@ class LinkedIn extends OAuth * * Basic Profile Fields: * https://developer.linkedin.com/docs/fields/basic-profile - * */ /** @@ -46,7 +45,7 @@ class LinkedIn extends OAuth */ public function getLoginURL():string { - return 'https://www.linkedin.com/oauth/v2/authorization?' . http_build_query([ + return 'https://www.linkedin.com/oauth/v2/authorization?'.http_build_query([ 'response_type' => 'code', 'client_id' => $this->appID, 'redirect_uri' => $this->callback, @@ -57,6 +56,7 @@ class LinkedIn extends OAuth /** * @param string $code + * * @return string */ public function getAccessToken(string $code):string @@ -73,7 +73,7 @@ class LinkedIn extends OAuth $accessToken = json_decode($accessToken, true); - if(isset($accessToken['access_token'])) { + if (isset($accessToken['access_token'])) { return $accessToken['access_token']; } @@ -82,13 +82,14 @@ class LinkedIn extends OAuth /** * @param $accessToken + * * @return string */ public function getUserID(string $accessToken):string { $user = $this->getUser($accessToken); - if(isset($user['id'])) { + if (isset($user['id'])) { return $user['id']; } @@ -97,19 +98,19 @@ class LinkedIn extends OAuth /** * @param $accessToken + * * @return string */ public function getUserEmail(string $accessToken):string { - $email = json_decode($this->request('GET', 'https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))', ['Authorization: Bearer ' . urlencode($accessToken)]), true); + $email = json_decode($this->request('GET', 'https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))', ['Authorization: Bearer '.urlencode($accessToken)]), true); - if( + if ( isset($email['elements']) && isset($email['elements'][0]) && isset($email['elements'][0]['handle~']) && isset($email['elements'][0]['handle~']['emailAddress']) - ) - { + ) { return $email['elements'][0]['handle~']['emailAddress']; } @@ -118,6 +119,7 @@ class LinkedIn extends OAuth /** * @param $accessToken + * * @return string */ public function getUserName(string $accessToken):string @@ -125,12 +127,12 @@ class LinkedIn extends OAuth $user = $this->getUser($accessToken); $name = ''; - if(isset($user['localizedFirstName'])) { + if (isset($user['localizedFirstName'])) { $name = $user['localizedFirstName']; } - if(isset($user['localizedLastName'])) { - $name = (empty($name)) ? $user['localizedLastName'] : $name . ' ' . $user['localizedLastName']; + if (isset($user['localizedLastName'])) { + $name = (empty($name)) ? $user['localizedLastName'] : $name.' '.$user['localizedLastName']; } return $name; @@ -138,14 +140,15 @@ class LinkedIn extends OAuth /** * @param string $accessToken + * * @return array */ protected function getUser(string $accessToken) { - if(empty($this->user)) { - $this->user = json_decode($this->request('GET', 'https://api.linkedin.com/v2/me', ['Authorization: Bearer ' . urlencode($accessToken)]), true); + if (empty($this->user)) { + $this->user = json_decode($this->request('GET', 'https://api.linkedin.com/v2/me', ['Authorization: Bearer '.urlencode($accessToken)]), true); } return $this->user; } -} \ No newline at end of file +} diff --git a/src/Auth/Validator/Password.php b/src/Auth/Validator/Password.php index ad74a93e7..f8441881a 100755 --- a/src/Auth/Validator/Password.php +++ b/src/Auth/Validator/Password.php @@ -5,16 +5,14 @@ namespace Auth\Validator; use Utopia\Validator; /** - * Password + * Password. * * Validates user password string - * - * @package Utopia\Validator */ class Password extends Validator { /** - * Get Description + * Get Description. * * Returns validator description * @@ -26,11 +24,12 @@ class Password extends Validator } /** - * Is valid + * Is valid. * * Validation username * - * @param mixed $value + * @param mixed $value + * * @return bool */ public function isValid($value) @@ -41,4 +40,4 @@ class Password extends Validator return true; } -} \ No newline at end of file +} diff --git a/src/Database/Adapter.php b/src/Database/Adapter.php index e36ba57e0..b61556e12 100644 --- a/src/Database/Adapter.php +++ b/src/Database/Adapter.php @@ -12,17 +12,19 @@ abstract class Adapter protected $namespace = ''; /** - * Set Namespace + * Set Namespace. * * Set namespace to divide different scope of data sets * * @param $namespace + * * @throws Exception + * * @return bool */ public function setNamespace($namespace) { - if(empty($namespace)) { + if (empty($namespace)) { throw new Exception('Missing namespace'); } @@ -32,16 +34,17 @@ abstract class Adapter } /** - * Get Namespace + * Get Namespace. * * Get namespace of current set scope * * @throws Exception + * * @return string */ public function getNamespace() { - if(empty($this->namespace)) { + if (empty($this->namespace)) { throw new Exception('Missing namespace'); } @@ -49,71 +52,80 @@ abstract class Adapter } /** - * Get Document + * Get Document. * * @param int $id + * * @return array */ abstract public function getDocument($id); /** * Create Document - ** + **. + * * @param array $data + * * @return array */ abstract public function createDocument(array $data); /** - * Update Document + * Update Document. * * @param array $data + * * @return array */ abstract public function updateDocument(array $data); /** - * Delete Node + * Delete Node. * * @param int $id + * * @return array */ abstract public function deleteDocument($id); /** - * Create Namespace + * Create Namespace. * * @param string $namespace + * * @return bool */ abstract public function createNamespace($namespace); /** - * Delete Namespace + * Delete Namespace. * * @param string $namespace + * * @return bool */ abstract public function deleteNamespace($namespace); /** - * Filter + * Filter. * * Filter data sets using chosen queries * * @param array $options + * * @return array */ abstract public function getCollection(array $options); /** * @param array $options + * * @return int */ abstract public function getCount(array $options); /** - * Last Modified + * Last Modified. * * Return unix timestamp of last time a node queried in corrent session has been changed * @@ -122,7 +134,7 @@ abstract class Adapter abstract public function lastModified(); /** - * Get Debug Data + * Get Debug Data. * * @return array */ diff --git a/src/Database/Adapter/MySQL.php b/src/Database/Adapter/MySQL.php index b193af650..c0aeccb9e 100644 --- a/src/Database/Adapter/MySQL.php +++ b/src/Database/Adapter/MySQL.php @@ -11,16 +11,16 @@ use Database\Validator\Authorization; class MySQL extends Adapter { - const DATA_TYPE_STRING = 'string'; - const DATA_TYPE_INTEGER = 'integer'; - const DATA_TYPE_FLOAT = 'float'; - const DATA_TYPE_BOOLEAN = 'boolean'; - const DATA_TYPE_OBJECT = 'object'; - const DATA_TYPE_DICTIONARY = 'dictionary'; - const DATA_TYPE_ARRAY = 'array'; - const DATA_TYPE_NULL = 'null'; + const DATA_TYPE_STRING = 'string'; + const DATA_TYPE_INTEGER = 'integer'; + const DATA_TYPE_FLOAT = 'float'; + const DATA_TYPE_BOOLEAN = 'boolean'; + const DATA_TYPE_OBJECT = 'object'; + const DATA_TYPE_DICTIONARY = 'dictionary'; + const DATA_TYPE_ARRAY = 'array'; + const DATA_TYPE_NULL = 'null'; - const OPTIONS_LIMIT_ATTRIBUTES = 1000; + const OPTIONS_LIMIT_ATTRIBUTES = 1000; /** * @var PDO @@ -28,21 +28,21 @@ class MySQL extends Adapter protected $register; /** - * Saved nodes + * Saved nodes. * * @var array */ protected $nodes = []; /** - * Count documents get usage + * Count documents get usage. * * @var int */ protected $count = 0; /** - * Last modified + * Last modified. * * Read node with most recent changes * @@ -56,7 +56,7 @@ class MySQL extends Adapter protected $debug = []; /** - * Constructor + * Constructor. * * Set connection and settings * @@ -64,22 +64,24 @@ class MySQL extends Adapter */ public function __construct(Registry $register) { - $this->register = $register; + $this->register = $register; } /** - * Get Document + * Get Document. * * @param string $id + * * @return array + * * @throws Exception */ public function getDocument($id) { - $this->count++; + ++$this->count; // Get fields abstraction - $st = $this->getPDO()->prepare('SELECT * FROM `' . $this->getNamespace() . '.database.documents` a + $st = $this->getPDO()->prepare('SELECT * FROM `'.$this->getNamespace().'.database.documents` a WHERE a.uid = :uid AND a.status = 0 ORDER BY a.updatedAt DESC LIMIT 10; '); @@ -95,7 +97,7 @@ class MySQL extends Adapter } // Get fields abstraction - $st = $this->getPDO()->prepare('SELECT * FROM `' . $this->getNamespace() . '.database.properties` a + $st = $this->getPDO()->prepare('SELECT * FROM `'.$this->getNamespace().'.database.properties` a WHERE a.documentUid = :documentUid AND a.documentRevision = :documentRevision ORDER BY `order` '); @@ -116,16 +118,15 @@ class MySQL extends Adapter foreach ($properties as &$property) { settype($property['value'], $property['primitive']); - if($property['array']) { + if ($property['array']) { $output[$property['key']][] = $property['value']; - } - else { + } else { $output[$property['key']] = $property['value']; } } // Get fields abstraction - $st = $this->getPDO()->prepare('SELECT * FROM `' . $this->getNamespace() . '.database.relationships` a + $st = $this->getPDO()->prepare('SELECT * FROM `'.$this->getNamespace().'.database.relationships` a WHERE a.start = :start AND revision = :revision ORDER BY `order` '); @@ -141,25 +142,27 @@ class MySQL extends Adapter } /** - * Create Document + * Create Document. * * @param array $data + * * @throws \Exception + * * @return array */ public function createDocument(array $data = []) { - $order = 0; - $data = array_merge(['$uid' => null, '$permissions' => []], $data); // Merge data with default params - $signature = md5(json_encode($data, true)); - $revision = uniqid('', true); + $order = 0; + $data = array_merge(['$uid' => null, '$permissions' => []], $data); // Merge data with default params + $signature = md5(json_encode($data, true)); + $revision = uniqid('', true); - /** + /* * When updating node, check if there are any changes to update * by comparing data md5 signatures */ - if(null !== $data['$uid']) { - $st = $this->getPDO()->prepare('SELECT signature FROM `' . $this->getNamespace() . '.database.documents` a + if (null !== $data['$uid']) { + $st = $this->getPDO()->prepare('SELECT signature FROM `'.$this->getNamespace().'.database.documents` a WHERE a.uid = :uid AND a.status = 0 ORDER BY a.updatedAt DESC LIMIT 1; '); @@ -170,67 +173,66 @@ class MySQL extends Adapter $oldSignature = $st->fetch()['signature']; - if($signature === $oldSignature) { + if ($signature === $oldSignature) { return $data; } } // Add or update fields abstraction level - $st1 = $this->getPDO()->prepare('INSERT INTO `' . $this->getNamespace() . '.database.documents` + $st1 = $this->getPDO()->prepare('INSERT INTO `'.$this->getNamespace().'.database.documents` SET uid = :uid, createdAt = :createdAt, updatedAt = :updatedAt, signature = :signature, revision = :revision, permissions = :permissions, status = 0 ON DUPLICATE KEY UPDATE uid = :uid, updatedAt = :updatedAt, signature = :signature, revision = :revision, permissions = :permissions; '); // Adding fields properties - if(null === $data['$uid'] || !isset($data['$uid'])) { // Get new fields UID + if (null === $data['$uid'] || !isset($data['$uid'])) { // Get new fields UID $data['$uid'] = $this->getUid(); } $st1->bindValue(':uid', $data['$uid'], PDO::PARAM_STR); $st1->bindValue(':revision', $revision, PDO::PARAM_STR); $st1->bindValue(':signature', $signature, PDO::PARAM_STR); - $st1->bindValue(':createdAt', date( 'Y-m-d H:i:s', time()),PDO::PARAM_STR); - $st1->bindValue(':updatedAt', date( 'Y-m-d H:i:s', time()),PDO::PARAM_STR); + $st1->bindValue(':createdAt', date('Y-m-d H:i:s', time()), PDO::PARAM_STR); + $st1->bindValue(':updatedAt', date('Y-m-d H:i:s', time()), PDO::PARAM_STR); $st1->bindValue(':permissions', json_encode($data['$permissions']), PDO::PARAM_STR); $st1->execute(); // Delete old properties - $rms1 = $this->getPDO()->prepare('DELETE FROM `' . $this->getNamespace() . '.database.properties` WHERE documentUid = :documentUid AND documentRevision != :documentRevision'); + $rms1 = $this->getPDO()->prepare('DELETE FROM `'.$this->getNamespace().'.database.properties` WHERE documentUid = :documentUid AND documentRevision != :documentRevision'); $rms1->bindValue(':documentUid', $data['$uid'], PDO::PARAM_STR); $rms1->bindValue(':documentRevision', $revision, PDO::PARAM_STR); $rms1->execute(); // Delete old relationships - $rms2 = $this->getPDO()->prepare('DELETE FROM `' . $this->getNamespace() . '.database.relationships` WHERE start = :start AND revision != :revision'); + $rms2 = $this->getPDO()->prepare('DELETE FROM `'.$this->getNamespace().'.database.relationships` WHERE start = :start AND revision != :revision'); $rms2->bindValue(':start', $data['$uid'], PDO::PARAM_STR); $rms2->bindValue(':revision', $revision, PDO::PARAM_STR); $rms2->execute(); // Create new properties - $st2 = $this->getPDO()->prepare('INSERT INTO `' . $this->getNamespace() . '.database.properties` + $st2 = $this->getPDO()->prepare('INSERT INTO `'.$this->getNamespace().'.database.properties` (`documentUid`, `documentRevision`, `key`, `value`, `primitive`, `array`, `order`) VALUES (:documentUid, :documentRevision, :key, :value, :primitive, :array, :order)'); $props = []; - foreach($data as $key => $value) { // Prepare properties data + foreach ($data as $key => $value) { // Prepare properties data - if(in_array($key, ['$permissions'])) { + if (in_array($key, ['$permissions'])) { continue; } $type = $this->getDataType($value); // Handle array of relations - if(self::DATA_TYPE_ARRAY === $type) { - foreach($value as $i => $child) { - - if(self::DATA_TYPE_DICTIONARY !== $this->getDataType($child)) { // not dictionary + if (self::DATA_TYPE_ARRAY === $type) { + foreach ($value as $i => $child) { + if (self::DATA_TYPE_DICTIONARY !== $this->getDataType($child)) { // not dictionary $props[] = [ - 'type' => $this->getDataType($child), - 'key' => $key, + 'type' => $this->getDataType($child), + 'key' => $key, 'value' => $child, 'array' => true, 'order' => $order++, @@ -248,20 +250,20 @@ class MySQL extends Adapter } // Handle relation - if(self::DATA_TYPE_DICTIONARY === $type) { + if (self::DATA_TYPE_DICTIONARY === $type) { $value = $this->createDocument($value); $this->createRelationship($revision, $data['$uid'], $value['$uid'], $key); //xxx continue; } // Handle empty values - if(self::DATA_TYPE_NULL === $type) { + if (self::DATA_TYPE_NULL === $type) { continue; } $props[] = [ - 'type' => $type, - 'key' => $key, + 'type' => $type, + 'key' => $key, 'value' => $value, 'array' => false, 'order' => $order++, @@ -269,8 +271,8 @@ class MySQL extends Adapter } foreach ($props as $prop) { - if(is_array($prop['value'])) { - throw new Exception('Value can\'t be an array: ' . json_encode($prop['value'])); + if (is_array($prop['value'])) { + throw new Exception('Value can\'t be an array: '.json_encode($prop['value'])); } $st2->bindValue(':documentUid', $data['$uid'], PDO::PARAM_STR); $st2->bindValue(':documentRevision', $revision, PDO::PARAM_STR); @@ -285,17 +287,19 @@ class MySQL extends Adapter } //TODO remove this dependency (check if related to nested documents) - $this->getRedis()->expire($this->getNamespace() . ':document-' . $data['$uid'], 0); - $this->getRedis()->expire($this->getNamespace() . ':document-' . $data['$uid'], 0); + $this->getRedis()->expire($this->getNamespace().':document-'.$data['$uid'], 0); + $this->getRedis()->expire($this->getNamespace().':document-'.$data['$uid'], 0); return $data; } /** - * Update Document + * Update Document. * * @param array $data + * * @return array + * * @throws Exception */ public function updateDocument(array $data = []) @@ -304,15 +308,17 @@ class MySQL extends Adapter } /** - * Delete Document + * Delete Document. * * @param int $id + * * @return array + * * @throws Exception */ public function deleteDocument($id) { - $st1 = $this->getPDO()->prepare('DELETE FROM `' . $this->getNamespace() . '.database.documents` + $st1 = $this->getPDO()->prepare('DELETE FROM `'.$this->getNamespace().'.database.documents` WHERE uid = :id '); @@ -320,7 +326,7 @@ class MySQL extends Adapter $st1->execute(); - $st2 = $this->getPDO()->prepare('DELETE FROM `' . $this->getNamespace() . '.database.properties` + $st2 = $this->getPDO()->prepare('DELETE FROM `'.$this->getNamespace().'.database.properties` WHERE documentUid = :id '); @@ -328,7 +334,7 @@ class MySQL extends Adapter $st2->execute(); - $st3 = $this->getPDO()->prepare('DELETE FROM `' . $this->getNamespace() . '.database.relationships` + $st3 = $this->getPDO()->prepare('DELETE FROM `'.$this->getNamespace().'.database.relationships` WHERE start = :id OR end = :id '); @@ -340,22 +346,24 @@ class MySQL extends Adapter } /** - * Create Relation + * Create Relation. * * Adds a new relationship between different nodes * * @param string $revision - * @param int $start - * @param int $end + * @param int $start + * @param int $end * @param string $key - * @param bool $isArray - * @param int $order + * @param bool $isArray + * @param int $order + * * @return array + * * @throws Exception */ protected function createRelationship($revision, $start, $end, $key, $isArray = false, $order = 0) { - $st2 = $this->getPDO()->prepare('INSERT INTO `' . $this->getNamespace() . '.database.relationships` + $st2 = $this->getPDO()->prepare('INSERT INTO `'.$this->getNamespace().'.database.relationships` (`revision`, `start`, `end`, `key`, `array`, `order`) VALUES (:revision, :start, :end, :key, :array, :order)'); @@ -372,32 +380,33 @@ class MySQL extends Adapter } /** - * Create Namespace + * Create Namespace. * * @param $namespace + * * @throws Exception + * * @return bool */ public function createNamespace($namespace) { - if(empty($namespace)) { + if (empty($namespace)) { throw new Exception('Empty namespace'); } - $documents = 'app_' . $namespace . '.database.documents'; - $properties = 'app_' . $namespace . '.database.properties'; - $relationships = 'app_' . $namespace . '.database.relationships'; - $audit = 'app_' . $namespace . '.audit.audit'; - $abuse = 'app_' . $namespace . '.abuse.abuse'; + $documents = 'app_'.$namespace.'.database.documents'; + $properties = 'app_'.$namespace.'.database.properties'; + $relationships = 'app_'.$namespace.'.database.relationships'; + $audit = 'app_'.$namespace.'.audit.audit'; + $abuse = 'app_'.$namespace.'.abuse.abuse'; try { - $this->getPDO()->prepare('CREATE TABLE `' . $documents . '` LIKE `template.database.documents`;')->execute(); - $this->getPDO()->prepare('CREATE TABLE `' . $properties . '` LIKE `template.database.properties`;')->execute(); - $this->getPDO()->prepare('CREATE TABLE `' . $relationships . '` LIKE `template.database.relationships`;')->execute(); - $this->getPDO()->prepare('CREATE TABLE `' . $audit .'` LIKE `template.audit.audit`;')->execute(); - $this->getPDO()->prepare('CREATE TABLE `' . $abuse . '` LIKE `template.abuse.abuse`;')->execute(); - } - catch (Exception $e) { + $this->getPDO()->prepare('CREATE TABLE `'.$documents.'` LIKE `template.database.documents`;')->execute(); + $this->getPDO()->prepare('CREATE TABLE `'.$properties.'` LIKE `template.database.properties`;')->execute(); + $this->getPDO()->prepare('CREATE TABLE `'.$relationships.'` LIKE `template.database.relationships`;')->execute(); + $this->getPDO()->prepare('CREATE TABLE `'.$audit.'` LIKE `template.audit.audit`;')->execute(); + $this->getPDO()->prepare('CREATE TABLE `'.$abuse.'` LIKE `template.abuse.abuse`;')->execute(); + } catch (Exception $e) { throw $e; } @@ -405,32 +414,33 @@ class MySQL extends Adapter } /** - * Delete Namespace + * Delete Namespace. * * @param $namespace + * * @throws Exception + * * @return bool */ public function deleteNamespace($namespace) { - if(empty($namespace)) { + if (empty($namespace)) { throw new Exception('Empty namespace'); } - $documents = 'app_' . $namespace . '.database.documents'; - $properties = 'app_' . $namespace . '.database.properties'; - $relationships = 'app_' . $namespace . '.database.relationships'; - $audit = 'app_' . $namespace . '.audit.audit'; - $abuse = 'app_' . $namespace . '.abuse.abuse'; + $documents = 'app_'.$namespace.'.database.documents'; + $properties = 'app_'.$namespace.'.database.properties'; + $relationships = 'app_'.$namespace.'.database.relationships'; + $audit = 'app_'.$namespace.'.audit.audit'; + $abuse = 'app_'.$namespace.'.abuse.abuse'; try { - $this->getPDO()->prepare('DROP TABLE `' . $documents . '`;')->execute(); - $this->getPDO()->prepare('DROP TABLE `' . $properties . '`;')->execute(); - $this->getPDO()->prepare('DROP TABLE `' . $relationships . '`;')->execute(); - $this->getPDO()->prepare('DROP TABLE `' . $audit .'`;')->execute(); - $this->getPDO()->prepare('DROP TABLE `' . $abuse . '`;')->execute(); - } - catch (Exception $e) { + $this->getPDO()->prepare('DROP TABLE `'.$documents.'`;')->execute(); + $this->getPDO()->prepare('DROP TABLE `'.$properties.'`;')->execute(); + $this->getPDO()->prepare('DROP TABLE `'.$relationships.'`;')->execute(); + $this->getPDO()->prepare('DROP TABLE `'.$audit.'`;')->execute(); + $this->getPDO()->prepare('DROP TABLE `'.$abuse.'`;')->execute(); + } catch (Exception $e) { throw $e; } @@ -438,84 +448,83 @@ class MySQL extends Adapter } /** - * Get Collection + * Get Collection. * * @param array $options + * * @throws Exception + * * @return array */ public function getCollection(array $options) { - $start = microtime(true); - $orderCastMap = [ - 'int' => 'UNSIGNED', - 'string' => 'CHAR', - 'date' => 'DATE', - 'time' => 'TIME', - 'datetime' => 'DATETIME', + $start = microtime(true); + $orderCastMap = [ + 'int' => 'UNSIGNED', + 'string' => 'CHAR', + 'date' => 'DATE', + 'time' => 'TIME', + 'datetime' => 'DATETIME', ]; - $orderTypeMap = ['DESC', 'ASC']; + $orderTypeMap = ['DESC', 'ASC']; $options['orderField'] = (empty($options['orderField'])) ? '$uid' : $options['orderField']; // Set default order field $options['orderCast'] = (empty($options['orderCast'])) ? 'string' : $options['orderCast']; // Set default order field - if(!array_key_exists($options['orderCast'], $orderCastMap)) { + if (!array_key_exists($options['orderCast'], $orderCastMap)) { throw new Exception('Invalid order cast'); } - if(!in_array($options['orderType'], $orderTypeMap)) { + if (!in_array($options['orderType'], $orderTypeMap)) { throw new Exception('Invalid order type'); } - $where = []; - $join = []; - $sorts = []; + $where = []; + $join = []; + $sorts = []; $search = ''; // Filters - foreach($options['filters'] as $i => $filter) { - $filter = $this->parseFilter($filter); - $key = $filter['key']; - $value = $filter['value']; - $operator = $filter['operator']; + foreach ($options['filters'] as $i => $filter) { + $filter = $this->parseFilter($filter); + $key = $filter['key']; + $value = $filter['value']; + $operator = $filter['operator']; - $path = explode('.', $key); - $original = $path; + $path = explode('.', $key); + $original = $path; - if(1 < count($path)) { + if (1 < count($path)) { $key = array_pop($path); - } - else { + } else { $path = []; } //$path = implode('.', $path); - $key = $this->getPDO()->quote($key, PDO::PARAM_STR); - $value = $this->getPDO()->quote($value, PDO::PARAM_STR); + $key = $this->getPDO()->quote($key, PDO::PARAM_STR); + $value = $this->getPDO()->quote($value, PDO::PARAM_STR); //$path = $this->getPDO()->quote($path, PDO::PARAM_STR); - $options['offset'] = (int)$options['offset']; - $options['limit'] = (int)$options['limit']; + $options['offset'] = (int) $options['offset']; + $options['limit'] = (int) $options['limit']; - if(empty($path)) {//if($path == "''") { // Handle direct attributes queries - $where[] = "JOIN `" . $this->getNamespace() . ".database.properties` b{$i} ON a.uid IS NOT NULL AND b{$i}.documentUid = a.uid AND (b{$i}.key = {$key} AND b{$i}.value {$operator} {$value})"; - } - else { // Handle direct child attributes queries + if (empty($path)) { + //if($path == "''") { // Handle direct attributes queries + $where[] = 'JOIN `'.$this->getNamespace().".database.properties` b{$i} ON a.uid IS NOT NULL AND b{$i}.documentUid = a.uid AND (b{$i}.key = {$key} AND b{$i}.value {$operator} {$value})"; + } else { // Handle direct child attributes queries $len = count($original); - $prev = 'c' . $i; + $prev = 'c'.$i; foreach ($original as $y => $part) { $part = $this->getPDO()->quote($part, PDO::PARAM_STR); - if(0 === $y) { // First key - $join[$i] = "JOIN `" . $this->getNamespace() . ".database.relationships` c{$i} ON a.uid IS NOT NULL AND c{$i}.start = a.uid AND c{$i}.key = {$part}"; - } - else if ($y == $len - 1) { // Last key - $join[$i] .= "JOIN `" . $this->getNamespace() . ".database.properties` e{$i} ON e{$i}.documentUid = {$prev}.end AND e{$i}.key = {$part} AND e{$i}.value {$operator} {$value}"; - } - else { - $join[$i] .= "JOIN `" . $this->getNamespace() . ".database.relationships` d{$i}{$y} ON d{$i}{$y}.start = {$prev}.end AND d{$i}{$y}.key = {$part}"; - $prev = 'd' . $i . $y; + if (0 === $y) { // First key + $join[$i] = 'JOIN `'.$this->getNamespace().".database.relationships` c{$i} ON a.uid IS NOT NULL AND c{$i}.start = a.uid AND c{$i}.key = {$part}"; + } elseif ($y == $len - 1) { // Last key + $join[$i] .= 'JOIN `'.$this->getNamespace().".database.properties` e{$i} ON e{$i}.documentUid = {$prev}.end AND e{$i}.key = {$part} AND e{$i}.value {$operator} {$value}"; + } else { + $join[$i] .= 'JOIN `'.$this->getNamespace().".database.relationships` d{$i}{$y} ON d{$i}{$y}.start = {$prev}.end AND d{$i}{$y}.key = {$part}"; + $prev = 'd'.$i.$y; } } @@ -525,44 +534,42 @@ class MySQL extends Adapter } // Sorting - $orderPath = explode('.', $options['orderField']); - $len = count($orderPath); - $orderKey = 'order_b'; - $part = $this->getPDO()->quote(implode('', $orderPath), PDO::PARAM_STR); - $orderSelect = "CASE WHEN {$orderKey}.key = {$part} THEN CAST({$orderKey}.value AS {$orderCastMap[$options['orderCast']]}) END AS sort_ff"; + $orderPath = explode('.', $options['orderField']); + $len = count($orderPath); + $orderKey = 'order_b'; + $part = $this->getPDO()->quote(implode('', $orderPath), PDO::PARAM_STR); + $orderSelect = "CASE WHEN {$orderKey}.key = {$part} THEN CAST({$orderKey}.value AS {$orderCastMap[$options['orderCast']]}) END AS sort_ff"; - if(1 === $len) {//if($path == "''") { // Handle direct attributes queries - $sorts[] = "LEFT JOIN `" . $this->getNamespace() . ".database.properties` order_b ON a.uid IS NOT NULL AND order_b.documentUid = a.uid AND (order_b.key = {$part})"; - } - else { // Handle direct child attributes queries + if (1 === $len) { + //if($path == "''") { // Handle direct attributes queries + $sorts[] = 'LEFT JOIN `'.$this->getNamespace().".database.properties` order_b ON a.uid IS NOT NULL AND order_b.documentUid = a.uid AND (order_b.key = {$part})"; + } else { // Handle direct child attributes queries $prev = 'c'; $orderKey = 'order_e'; foreach ($orderPath as $y => $part) { - $part = $this->getPDO()->quote($part, PDO::PARAM_STR); - $x = $y -1; + $part = $this->getPDO()->quote($part, PDO::PARAM_STR); + $x = $y - 1; - if(0 === $y) { // First key - $sorts[] = "JOIN `" . $this->getNamespace() . ".database.relationships` order_c{$y} ON a.uid IS NOT NULL AND order_c{$y}.start = a.uid AND order_c{$y}.key = {$part}"; - } - else if ($y == $len - 1) { // Last key - $sorts[] .= "JOIN `" . $this->getNamespace() . ".database.properties` order_e ON order_e.documentUid = order_{$prev}{$x}.end AND order_e.key = {$part}"; - } - else { - $sorts[] .= "JOIN `" . $this->getNamespace() . ".database.relationships` order_d{$y} ON order_d{$y}.start = order_{$prev}{$x}.end AND order_d{$y}.key = {$part}"; + if (0 === $y) { // First key + $sorts[] = 'JOIN `'.$this->getNamespace().".database.relationships` order_c{$y} ON a.uid IS NOT NULL AND order_c{$y}.start = a.uid AND order_c{$y}.key = {$part}"; + } elseif ($y == $len - 1) { // Last key + $sorts[] .= 'JOIN `'.$this->getNamespace().".database.properties` order_e ON order_e.documentUid = order_{$prev}{$x}.end AND order_e.key = {$part}"; + } else { + $sorts[] .= 'JOIN `'.$this->getNamespace().".database.relationships` order_d{$y} ON order_d{$y}.start = order_{$prev}{$x}.end AND order_d{$y}.key = {$part}"; $prev = 'd'; } } } - /** + /* * Workaround for a MySQL bug as reported here: * https://bugs.mysql.com/bug.php?id=78485 */ $options['search'] = ($options['search'] === '*') ? '' : $options['search']; // Search - if(!empty($options['search'])) { // Handle free search + if (!empty($options['search'])) { // Handle free search // $where[] = "LEFT JOIN `" . $this->getNamespace() . ".database.properties` b_search ON a.uid IS NOT NULL AND b_search.documentUid = a.uid // LEFT JOIN // `" . $this->getNamespace() . ".database.relationships` c_search ON c_search.start = a.uid @@ -580,11 +587,11 @@ class MySQL extends Adapter // OR MATCH (f_search.value) AGAINST ({$this->getPDO()->quote($options['search'], PDO::PARAM_STR)} IN BOOLEAN MODE) // OR f_search.value LIKE {$this->getPDO()->quote('%%' . $options['search'] . '%%', PDO::PARAM_STR)})"; - $where[] = "LEFT JOIN `" . $this->getNamespace() . ".database.properties` b_search ON a.uid IS NOT NULL AND b_search.documentUid = a.uid AND b_search.primitive = 'string' + $where[] = 'LEFT JOIN `'.$this->getNamespace().".database.properties` b_search ON a.uid IS NOT NULL AND b_search.documentUid = a.uid AND b_search.primitive = 'string' LEFT JOIN - `" . $this->getNamespace() . ".database.relationships` c_search ON c_search.start = b_search.documentUid + `".$this->getNamespace().'.database.relationships` c_search ON c_search.start = b_search.documentUid LEFT JOIN - `" . $this->getNamespace() . ".database.properties` d_search ON d_search.documentUid = c_search.end AND d_search.primitive = 'string' + `'.$this->getNamespace().".database.properties` d_search ON d_search.documentUid = c_search.end AND d_search.primitive = 'string' \n"; $search = "AND (MATCH (b_search.value) AGAINST ({$this->getPDO()->quote($options['search'], PDO::PARAM_STR)} IN BOOLEAN MODE) @@ -593,25 +600,25 @@ class MySQL extends Adapter } $select = 'DISTINCT a.uid'; - $where = implode("\n", $where); - $join = implode("\n", $join); - $sorts = implode("\n", $sorts); - $range = "LIMIT {$options['offset']}, {$options['limit']}"; - $roles = []; + $where = implode("\n", $where); + $join = implode("\n", $join); + $sorts = implode("\n", $sorts); + $range = "LIMIT {$options['offset']}, {$options['limit']}"; + $roles = []; foreach (Authorization::getRoles() as $role) { - $roles[] = 'JSON_CONTAINS(REPLACE(a.permissions, \'{self}\', a.uid), \'"' . $role . '"\', \'$.read\')'; + $roles[] = 'JSON_CONTAINS(REPLACE(a.permissions, \'{self}\', a.uid), \'"'.$role.'"\', \'$.read\')'; } - if(false === Authorization::$status) { // FIXME temporary solution (hopefully) + if (false === Authorization::$status) { // FIXME temporary solution (hopefully) $roles = ['1=1']; } - $query = "SELECT %s, {$orderSelect} - FROM `" . $this->getNamespace() . ".database.documents` a {$where}{$join}{$sorts} + $query = "SELECT %s, {$orderSelect} + FROM `".$this->getNamespace().".database.documents` a {$where}{$join}{$sorts} WHERE status = 0 {$search} - AND (" . implode('||', $roles) . ") + AND (".implode('||', $roles).") ORDER BY sort_ff {$options['orderType']} %s"; $st = $this->getPDO()->prepare(sprintf($query, $select, $range)); @@ -621,7 +628,7 @@ class MySQL extends Adapter $results = ['data' => []]; // Get entire fields data for each id - foreach($st->fetchAll() as $node) { + foreach ($st->fetchAll() as $node) { $results['data'][] = $node['uid']; } @@ -634,12 +641,12 @@ class MySQL extends Adapter $this->resetDebug(); $this - ->setDebug('query', preg_replace('/\s+/', ' ',sprintf($query, $select, $range))) + ->setDebug('query', preg_replace('/\s+/', ' ', sprintf($query, $select, $range))) ->setDebug('time', microtime(true) - $start) ->setDebug('filters', count($options['filters'])) ->setDebug('joins', substr_count($query, 'JOIN')) ->setDebug('count', count($results['data'])) - ->setDebug('sum', (int)$count['sum']) + ->setDebug('sum', (int) $count['sum']) ->setDebug('documents', $this->count) ; @@ -647,80 +654,79 @@ class MySQL extends Adapter } /** - * Get Collection + * Get Collection. * * @param array $options + * * @throws Exception + * * @return int */ public function getCount(array $options) { - $start = microtime(true); - $where = []; - $join = []; + $start = microtime(true); + $where = []; + $join = []; // Filters - foreach($options['filters'] as $i => $filter) { - $filter = $this->parseFilter($filter); - $key = $filter['key']; - $value = $filter['value']; - $operator = $filter['operator']; - $path = explode('.', $key); - $original = $path; + foreach ($options['filters'] as $i => $filter) { + $filter = $this->parseFilter($filter); + $key = $filter['key']; + $value = $filter['value']; + $operator = $filter['operator']; + $path = explode('.', $key); + $original = $path; - if(1 < count($path)) { + if (1 < count($path)) { $key = array_pop($path); - } - else { + } else { $path = []; } - $key = $this->getPDO()->quote($key, PDO::PARAM_STR); - $value = $this->getPDO()->quote($value, PDO::PARAM_STR); + $key = $this->getPDO()->quote($key, PDO::PARAM_STR); + $value = $this->getPDO()->quote($value, PDO::PARAM_STR); - if(empty($path)) {//if($path == "''") { // Handle direct attributes queries - $where[] = "JOIN `" . $this->getNamespace() . ".database.properties` b{$i} ON a.uid IS NOT NULL AND b{$i}.documentUid = a.uid AND (b{$i}.key = {$key} AND b{$i}.value {$operator} {$value})"; - } - else { // Handle direct child attributes queries - $len = count($original); - $prev = 'c' . $i; + if (empty($path)) { + //if($path == "''") { // Handle direct attributes queries + $where[] = 'JOIN `'.$this->getNamespace().".database.properties` b{$i} ON a.uid IS NOT NULL AND b{$i}.documentUid = a.uid AND (b{$i}.key = {$key} AND b{$i}.value {$operator} {$value})"; + } else { // Handle direct child attributes queries + $len = count($original); + $prev = 'c'.$i; foreach ($original as $y => $part) { $part = $this->getPDO()->quote($part, PDO::PARAM_STR); - if(0 === $y) { // First key - $join[$i] = "JOIN `" . $this->getNamespace() . ".database.relationships` c{$i} ON a.uid IS NOT NULL AND c{$i}.start = a.uid AND c{$i}.key = {$part}"; - } - else if ($y == $len - 1) { // Last key - $join[$i] .= "JOIN `" . $this->getNamespace() . ".database.properties` e{$i} ON e{$i}.documentUid = {$prev}.end AND e{$i}.key = {$part} AND e{$i}.value {$operator} {$value}"; - } - else { - $join[$i] .= "JOIN `" . $this->getNamespace() . ".database.relationships` d{$i}{$y} ON d{$i}{$y}.start = {$prev}.end AND d{$i}{$y}.key = {$part}"; - $prev = 'd' . $i . $y; + if (0 === $y) { // First key + $join[$i] = 'JOIN `'.$this->getNamespace().".database.relationships` c{$i} ON a.uid IS NOT NULL AND c{$i}.start = a.uid AND c{$i}.key = {$part}"; + } elseif ($y == $len - 1) { // Last key + $join[$i] .= 'JOIN `'.$this->getNamespace().".database.properties` e{$i} ON e{$i}.documentUid = {$prev}.end AND e{$i}.key = {$part} AND e{$i}.value {$operator} {$value}"; + } else { + $join[$i] .= 'JOIN `'.$this->getNamespace().".database.relationships` d{$i}{$y} ON d{$i}{$y}.start = {$prev}.end AND d{$i}{$y}.key = {$part}"; + $prev = 'd'.$i.$y; } } } } - $where = implode("\n", $where); - $join = implode("\n", $join); - $func = "JOIN `" . $this->getNamespace() . ".database.properties` b_func ON a.uid IS NOT NULL + $where = implode("\n", $where); + $join = implode("\n", $join); + $func = 'JOIN `'.$this->getNamespace().".database.properties` b_func ON a.uid IS NOT NULL AND a.uid = b_func.documentUid AND (b_func.key = 'sizeOriginal')"; - $roles = []; + $roles = []; foreach (Authorization::getRoles() as $role) { - $roles[] = 'JSON_CONTAINS(REPLACE(a.permissions, \'{self}\', a.uid), \'"' . $role . '"\', \'$.read\')'; + $roles[] = 'JSON_CONTAINS(REPLACE(a.permissions, \'{self}\', a.uid), \'"'.$role.'"\', \'$.read\')'; } - if(false === Authorization::$status) { // FIXME temporary solution (hopefully) + if (false === Authorization::$status) { // FIXME temporary solution (hopefully) $roles = ['1=1']; } - $query = "SELECT SUM(b_func.value) as result - FROM `" . $this->getNamespace() . ".database.documents` a {$where}{$join}{$func} + $query = 'SELECT SUM(b_func.value) as result + FROM `'.$this->getNamespace().".database.documents` a {$where}{$join}{$func} WHERE status = 0 - AND (" . implode('||', $roles) . ")"; + AND (".implode('||', $roles).')'; $st = $this->getPDO()->prepare(sprintf($query)); @@ -731,36 +737,36 @@ class MySQL extends Adapter $this->resetDebug(); $this - ->setDebug('query', preg_replace('/\s+/', ' ',sprintf($query))) + ->setDebug('query', preg_replace('/\s+/', ' ', sprintf($query))) ->setDebug('time', microtime(true) - $start) ->setDebug('filters', count($options['filters'])) ->setDebug('joins', substr_count($query, 'JOIN')) ; - return (int)(isset($result['result'])) ? $result['result'] : 0; + return (int) (isset($result['result'])) ? $result['result'] : 0; } /** - * Get Unique Document ID + * Get Unique Document ID. */ public function getUid() { - $unique = uniqid(); - $attempts = 5; + $unique = uniqid(); + $attempts = 5; - for ($i = 1; $i <= $attempts; $i++) { + for ($i = 1; $i <= $attempts; ++$i) { $document = $this->getDocument($unique); - if(empty($document) || $document['$uid'] !== $unique) { + if (empty($document) || $document['$uid'] !== $unique) { return $unique; } } - throw new Exception('Failed to create a unique ID (' . $attempts . ' attempts)'); + throw new Exception('Failed to create a unique ID ('.$attempts.' attempts)'); } /** - * Last Modified + * Last Modified. * * Return unix timestamp of last time a node queried in corrent session has been changed * @@ -772,15 +778,17 @@ class MySQL extends Adapter } /** - * Parse Filter + * Parse Filter. * * @param string $filter + * * @return array + * * @throws Exception */ protected function parseFilter($filter) { - $operatorsMap = ['!=', '>=', '<=', '=', '>', '<']; // Do not edit order of this array + $operatorsMap = ['!=', '>=', '<=', '=', '>', '<']; // Do not edit order of this array //FIXME bug with >= <= operators @@ -793,13 +801,13 @@ class MySQL extends Adapter } } - if(empty($operator)) { + if (empty($operator)) { throw new Exception('Invalid operator'); } $filter = explode($operator, $filter); - if(count($filter) != 2) { + if (count($filter) != 2) { throw new Exception('Invalid filter expression'); } @@ -811,18 +819,20 @@ class MySQL extends Adapter } /** - * Get Data Type + * Get Data Type. * * Check value data type. return value can be on of the following: * string, integer, float, boolean, object, list or null * * @param $value + * * @return string + * * @throws \Exception */ protected function getDataType($value) { - switch(gettype($value)) { + switch (gettype($value)) { case 'string': return self::DATA_TYPE_STRING; @@ -841,7 +851,7 @@ class MySQL extends Adapter break; case 'array': - if((bool)count(array_filter(array_keys($value), 'is_string'))) { + if ((bool) count(array_filter(array_keys($value), 'is_string'))) { return self::DATA_TYPE_DICTIONARY; } @@ -853,12 +863,13 @@ class MySQL extends Adapter break; } - throw new Exception('Unknown data type: ' . $value . ' (' . gettype($value) . ')'); + throw new Exception('Unknown data type: '.$value.' ('.gettype($value).')'); } /** * @param $key * @param $value + * * @return $this */ public function setDebug($key, $value) @@ -877,15 +888,16 @@ class MySQL extends Adapter } /** - * return $this; + * return $this;. */ public function resetDebug() { - $this->debug =[]; + $this->debug = []; } /** * @return PDO + * * @throws Exception */ protected function getPDO():PDO @@ -895,10 +907,11 @@ class MySQL extends Adapter /** * @throws Exception + * * @return Client */ protected function getRedis():Client { return $this->register->get('cache'); } -} \ No newline at end of file +} diff --git a/src/Database/Adapter/Redis.php b/src/Database/Adapter/Redis.php index 9a856748e..d73075554 100644 --- a/src/Database/Adapter/Redis.php +++ b/src/Database/Adapter/Redis.php @@ -21,29 +21,32 @@ class Redis extends Adapter /** * Redis constructor. - * @param Adapter $adapter + * + * @param Adapter $adapter * @param Registry $register */ public function __construct(Adapter $adapter, Registry $register) { $this->register = $register; - $this->adapter = $adapter; + $this->adapter = $adapter; } /** - * Get Document + * Get Document. * * @param string $id + * * @return array + * * @throws Exception */ public function getDocument($id) { - $output = json_decode($this->getRedis()->get($this->getNamespace() . ':document-' . $id), true); + $output = json_decode($this->getRedis()->get($this->getNamespace().':document-'.$id), true); - if(!$output) { + if (!$output) { $output = $this->adapter->getDocument($id); - $this->getRedis()->set($this->getNamespace() . ':document-' . $id, json_encode($output, JSON_UNESCAPED_UNICODE)); + $this->getRedis()->set($this->getNamespace().':document-'.$id, json_encode($output, JSON_UNESCAPED_UNICODE)); } $output = $this->parseRelations($output); @@ -53,36 +56,37 @@ class Redis extends Adapter /** * @param $output + * * @return mixed + * * @throws Exception */ protected function parseRelations($output) { $keys = []; - if(empty($output) || !isset($output['temp-relations'])) { + if (empty($output) || !isset($output['temp-relations'])) { return $output; } - foreach($output['temp-relations'] as $relationship) { - $keys[] = $this->getNamespace() . ':document-' . $relationship['end']; + foreach ($output['temp-relations'] as $relationship) { + $keys[] = $this->getNamespace().':document-'.$relationship['end']; } $nodes = (!empty($keys)) ? $this->getRedis()->mget($keys) : []; - foreach($output['temp-relations'] as $i => $relationship) { + foreach ($output['temp-relations'] as $i => $relationship) { $node = $relationship['end']; $node = (!empty($nodes[$i])) ? $this->parseRelations(json_decode($nodes[$i], true)) : $this->getDocument($node); - if(empty($node)) { + if (empty($node)) { continue; } - if($relationship['array']) { + if ($relationship['array']) { $output[$relationship['key']][] = $node; - } - else { + } else { $output[$relationship['key']] = $node; } } @@ -93,60 +97,67 @@ class Redis extends Adapter } /** - * Create Document + * Create Document. * * @param array $data + * * @return array + * * @throws Exception */ public function createDocument(array $data = []) { $data = $this->adapter->createDocument($data); - $this->getRedis()->expire($this->getNamespace() . ':document-' . $data['$uid'], 0); - $this->getRedis()->expire($this->getNamespace() . ':document-' . $data['$uid'], 0); + $this->getRedis()->expire($this->getNamespace().':document-'.$data['$uid'], 0); + $this->getRedis()->expire($this->getNamespace().':document-'.$data['$uid'], 0); return $data; } /** - * Update Document + * Update Document. * * @param array $data + * * @return array + * * @throws Exception */ public function updateDocument(array $data = []) { $data = $this->adapter->updateDocument($data); - $this->getRedis()->expire($this->getNamespace() . ':document-' . $data['$uid'], 0); - $this->getRedis()->expire($this->getNamespace() . ':document-' . $data['$uid'], 0); + $this->getRedis()->expire($this->getNamespace().':document-'.$data['$uid'], 0); + $this->getRedis()->expire($this->getNamespace().':document-'.$data['$uid'], 0); return $data; } /** - * Delete Document + * Delete Document. * * @param $id + * * @return array + * * @throws Exception */ public function deleteDocument($id) { $data = $this->adapter->deleteDocument($id); - $this->getRedis()->expire($this->getNamespace() . ':document-' . $id, 0); - $this->getRedis()->expire($this->getNamespace() . ':document-' . $id, 0); + $this->getRedis()->expire($this->getNamespace().':document-'.$id, 0); + $this->getRedis()->expire($this->getNamespace().':document-'.$id, 0); return $data; } /** - * Create Namespace + * Create Namespace. * * @param string $namespace + * * @return bool */ public function createNamespace($namespace) @@ -155,9 +166,10 @@ class Redis extends Adapter } /** - * Delete Namespace + * Delete Namespace. * * @param string $namespace + * * @return bool */ public function deleteNamespace($namespace) @@ -167,7 +179,9 @@ class Redis extends Adapter /** * @param array $options + * * @return array + * * @throws Exception */ public function getCollection(array $options) @@ -175,16 +189,16 @@ class Redis extends Adapter $data = $this->adapter->getCollection($options); $keys = []; - foreach($data as $node) { - $keys[] = $this->getNamespace() . ':document-' . $node; + foreach ($data as $node) { + $keys[] = $this->getNamespace().':document-'.$node; } $nodes = (!empty($keys)) ? $this->getRedis()->mget($keys) : []; - foreach($data as $i => &$node) { + foreach ($data as $i => &$node) { $temp = (!empty($nodes[$i])) ? $this->parseRelations(json_decode($nodes[$i], true)) : $this->getDocument($node); - if(!empty($temp)) { + if (!empty($temp)) { $node = $temp; } } @@ -194,7 +208,9 @@ class Redis extends Adapter /** * @param array $options + * * @return int + * * @throws Exception */ public function getCount(array $options) @@ -203,7 +219,7 @@ class Redis extends Adapter } /** - * Last Modified + * Last Modified. * * Return unix timestamp of last time a node queried in current session has been changed * @@ -211,7 +227,7 @@ class Redis extends Adapter */ public function lastModified() { - return null; + return; } /** @@ -224,6 +240,7 @@ class Redis extends Adapter /** * @throws Exception + * * @return Client */ protected function getRedis():Client @@ -232,12 +249,14 @@ class Redis extends Adapter } /** - * Set Namespace + * Set Namespace. * * Set namespace to divide different scope of data sets * * @param $namespace + * * @return bool + * * @throws Exception */ public function setNamespace($namespace) @@ -246,4 +265,4 @@ class Redis extends Adapter return parent::setNamespace($namespace); } -} \ No newline at end of file +} diff --git a/src/Database/Database.php b/src/Database/Database.php index a4e57584f..70acf4306 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -45,38 +45,44 @@ class Database protected $adapter; /** - * Set Adapter + * Set Adapter. * * @param Adapter $adapter + * * @return $this */ public function setAdapter(Adapter $adapter) { $this->adapter = $adapter; + return $this; } /** - * Set Namespace + * Set Namespace. * * Set namespace to divide different scope of data sets * * @param $namespace + * * @return $this + * * @throws Exception */ public function setNamespace($namespace) { $this->adapter->setNamespace($namespace); + return $this; } /** - * Get Namespace + * Get Namespace. * * Get namespace of current set scope * * @return string + * * @throws Exception */ public function getNamespace() @@ -85,9 +91,10 @@ class Database } /** - * Create Namespace + * Create Namespace. + * + * @param int $namespace * - * @param int $namespace * @return bool */ public function createNamespace($namespace) @@ -96,9 +103,10 @@ class Database } /** - * Delete Namespace + * Delete Namespace. + * + * @param int $namespace * - * @param int $namespace * @return bool */ public function deleteNamespace($namespace) @@ -108,6 +116,7 @@ class Database /** * @param array $options + * * @return Document[]|Document */ public function getCollection(array $options) @@ -127,15 +136,15 @@ class Database $results = $this->adapter->getCollection($options); - foreach($results as &$node) { + foreach ($results as &$node) { $node = new Document($node); } - if($options['first']) { + if ($options['first']) { $results = reset($results); } - if($options['last']) { + if ($options['last']) { $results = end($results); } @@ -143,21 +152,21 @@ class Database } /** - * @param int $id + * @param int $id * @param bool $mock is mocked data allowed? + * * @return Document */ public function getDocument($id, $mock = true) { - if(is_null($id)) { + if (is_null($id)) { return new Document([]); } - $document = new Document((isset($this->mocks[$id]) && $mock) ? $this->mocks[$id] : $this->adapter->getDocument($id)); - $validator = new Authorization($document, 'read'); + $document = new Document((isset($this->mocks[$id]) && $mock) ? $this->mocks[$id] : $this->adapter->getDocument($id)); + $validator = new Authorization($document, 'read'); - - if(!$validator->isValid($document->getPermissions())) { // Check if user has read access to this document + if (!$validator->isValid($document->getPermissions())) { // Check if user has read access to this document return new Document([]); } @@ -166,7 +175,9 @@ class Database /** * @param array $data + * * @return Document|bool + * * @throws AuthorizationException * @throws StructureException */ @@ -174,15 +185,15 @@ class Database { $document = new Document($data); - $validator = new Authorization($document, 'write'); + $validator = new Authorization($document, 'write'); - if(!$validator->isValid($document->getPermissions())) { // Check if user has write access to this document + if (!$validator->isValid($document->getPermissions())) { // Check if user has write access to this document throw new AuthorizationException($validator->getDescription()); } $validator = new Structure($this); - if(!$validator->isValid($document)) { + if (!$validator->isValid($document)) { throw new StructureException($validator->getDescription()); // var_dump($validator->getDescription()); return false; } @@ -191,12 +202,14 @@ class Database /** * @param array $data + * * @return Document|false + * * @throws Exception */ public function updateDocument(array $data) { - if(!isset($data['$uid'])) { + if (!isset($data['$uid'])) { throw new Exception('Must define $uid attribute'); } @@ -206,21 +219,21 @@ class Database $data['$uid'] = $document->getUid(); $data['$collection'] = $document->getCollection(); - $validator = new Authorization($document, 'write'); + $validator = new Authorization($document, 'write'); - if(!$validator->isValid($document->getPermissions())) { // Check if user has write access to this document + if (!$validator->isValid($document->getPermissions())) { // Check if user has write access to this document throw new AuthorizationException($validator->getDescription()); // var_dump($validator->getDescription()); return false; } $new = new Document($data); - if(!$validator->isValid($new->getPermissions())) { // Check if user has write access to this document + if (!$validator->isValid($new->getPermissions())) { // Check if user has write access to this document throw new AuthorizationException($validator->getDescription()); // var_dump($validator->getDescription()); return false; } $validator = new Structure($this); - if(!$validator->isValid($new)) { // Make sure updated structure still apply collection rules (if any) + if (!$validator->isValid($new)) { // Make sure updated structure still apply collection rules (if any) throw new StructureException($validator->getDescription()); // var_dump($validator->getDescription()); return false; } @@ -229,16 +242,18 @@ class Database /** * @param int $id + * * @return Document|false + * * @throws AuthorizationException */ public function deleteDocument($id) { $document = $this->getDocument($id); - $validator = new Authorization($document, 'write'); + $validator = new Authorization($document, 'write'); - if(!$validator->isValid($document->getPermissions())) { // Check if user has write access to this document + if (!$validator->isValid($document->getPermissions())) { // Check if user has write access to this document throw new AuthorizationException($validator->getDescription()); } @@ -265,6 +280,7 @@ class Database /** * @param array $options + * * @return int */ public function getCount(array $options) @@ -281,31 +297,38 @@ class Database /** * @param string $key * @param string $value + * * @return array */ - public function setMock($key, $value) { + public function setMock($key, $value) + { $this->mocks[$key] = $value; + return $this; } /** * @param string $mocks + * * @return array */ - public function setMocks(array $mocks) { + public function setMocks(array $mocks) + { $this->mocks = $mocks; + return $this; } /** * @return array */ - public function getMocks() { + public function getMocks() + { return $this->mocks; } /** - * Get Last Modified + * Get Last Modified. * * Return unix timestamp of last time a node queried in current session has been changed * @@ -315,4 +338,4 @@ class Database { return $this->adapter->lastModified(); } -} \ No newline at end of file +} diff --git a/src/Database/Document.php b/src/Database/Document.php index 0aa3aa548..1f7b5ff4a 100644 --- a/src/Database/Document.php +++ b/src/Database/Document.php @@ -6,30 +6,30 @@ use ArrayObject; class Document extends ArrayObject { - const SET_TYPE_ASSIGN = 'assign'; - const SET_TYPE_PREPEND = 'prepend'; - const SET_TYPE_APPEND = 'append'; + const SET_TYPE_ASSIGN = 'assign'; + const SET_TYPE_PREPEND = 'prepend'; + const SET_TYPE_APPEND = 'append'; /** - * Construct + * Construct. * * Construct a new fields object * * @see ArrayObject::__construct - * @param null $input - * @param int $flags + * + * @param null $input + * @param int $flags * @param string $iterator_class */ - public function __construct($input = null, $flags = 0, $iterator_class = "ArrayIterator") + public function __construct($input = null, $flags = 0, $iterator_class = 'ArrayIterator') { - foreach($input as $key => &$value) { - if(is_array($value)) { - if(isset($value['$uid']) || isset($value['$collection'])){ + foreach ($input as $key => &$value) { + if (is_array($value)) { + if (isset($value['$uid']) || isset($value['$collection'])) { $input[$key] = new self($value); - } - else { + } else { foreach ($value as $childKey => $child) { - if(isset($child['$uid']) || isset($child['$collection'])){ + if (isset($child['$uid']) || isset($child['$collection'])) { $value[$childKey] = new self($child); } } @@ -65,12 +65,13 @@ class Document extends ArrayObject } /** - * Get Attribute + * Get Attribute. * * Method for getting a specific fields attribute. If $name is not found $default value will be returned. * - * @param string $name - * @param mixed $default + * @param string $name + * @param mixed $default + * * @return mixed */ public function getAttribute($name, $default = null) @@ -79,8 +80,8 @@ class Document extends ArrayObject $temp = &$this; - foreach($name as $key) { - if(!isset($temp[$key])) { + foreach ($name as $key) { + if (!isset($temp[$key])) { return $default; } @@ -91,13 +92,14 @@ class Document extends ArrayObject } /** - * Set Attribute + * Set Attribute. * * Method for setting a specific field attribute * - * @param string $key - * @param mixed $value + * @param string $key + * @param mixed $value * @param string $type + * * @return mixed */ public function setAttribute($key, $value, $type = self::SET_TYPE_ASSIGN) @@ -120,33 +122,33 @@ class Document extends ArrayObject } /** - * Search + * Search. * * Get array child by key and value match * * @param $key * @param $value * @param array|null $scope + * * @return Document|Document[]|mixed|null|array */ public function search($key, $value, $scope = null) { $array = (!is_null($scope)) ? $scope : $this; - if(is_array($array) || $array instanceof self) { - if(isset($array[$key]) && $array[$key] == $value) { + if (is_array($array) || $array instanceof self) { + if (isset($array[$key]) && $array[$key] == $value) { return $array; } foreach ($array as $k => $v) { - if((is_array($v) || $v instanceof self) && (!empty($v))) { + if ((is_array($v) || $v instanceof self) && (!empty($v))) { $result = $this->search($key, $value, $v); - if(!empty($result)) { + if (!empty($result)) { return $result; } - } - else { + } else { if ($k === $key && $v === $value) { return $array; } @@ -154,15 +156,15 @@ class Document extends ArrayObject } } - if($array === $value) { + if ($array === $value) { return $array; } - return null; + return; } /** - * Checks if document has data + * Checks if document has data. * * @return bool */ @@ -172,12 +174,13 @@ class Document extends ArrayObject } /** - * Get Array Copy + * Get Array Copy. * * Outputs entity as a PHP array * * @param array $whitelist * @param array $blacklist + * * @return array */ public function getArrayCopy(array $whitelist = [], array $blacklist = []) @@ -187,36 +190,33 @@ class Document extends ArrayObject $output = array(); foreach ($array as $key => &$value) { - if(!empty($whitelist) && !in_array($key, $whitelist)) { // Export only whitelisted fields + if (!empty($whitelist) && !in_array($key, $whitelist)) { // Export only whitelisted fields continue; } - if(!empty($blacklist) && in_array($key, $blacklist)) { // Don't export blacklisted fields + if (!empty($blacklist) && in_array($key, $blacklist)) { // Don't export blacklisted fields continue; } if ($value instanceof self) { $output[$key] = $value->getArrayCopy($whitelist, $blacklist); - } - elseif (is_array($value)) { + } elseif (is_array($value)) { foreach ($value as $childKey => &$child) { if ($child instanceof self) { $output[$key][$childKey] = $child->getArrayCopy($whitelist, $blacklist); - } - else { + } else { $output[$key][$childKey] = $child; } } - if(empty($value)) { + if (empty($value)) { $output[$key] = $value; } - } - else { + } else { $output[$key] = $value; } } return $output; } -} \ No newline at end of file +} diff --git a/src/Database/Exception/Authorization.php b/src/Database/Exception/Authorization.php index ff3bba6be..264e44d99 100644 --- a/src/Database/Exception/Authorization.php +++ b/src/Database/Exception/Authorization.php @@ -4,5 +4,4 @@ namespace Database\Exception; class Authorization extends \Exception { - -} \ No newline at end of file +} diff --git a/src/Database/Exception/Structure.php b/src/Database/Exception/Structure.php index 3173ef976..e8ff72a12 100644 --- a/src/Database/Exception/Structure.php +++ b/src/Database/Exception/Structure.php @@ -4,5 +4,4 @@ namespace Database\Exception; class Structure extends \Exception { - -} \ No newline at end of file +} diff --git a/src/Database/Validator/Authorization.php b/src/Database/Validator/Authorization.php index b8f085707..dc46fc653 100644 --- a/src/Database/Validator/Authorization.php +++ b/src/Database/Validator/Authorization.php @@ -10,7 +10,7 @@ class Authorization extends Validator /** * @var array */ - static protected $roles = ['*']; + protected static $roles = ['*']; /** * @var Document @@ -31,7 +31,7 @@ class Authorization extends Validator * Structure constructor. * * @param Document $document - * @param string $action + * @param string $action */ public function __construct(Document $document, $action) { @@ -40,7 +40,7 @@ class Authorization extends Validator } /** - * Get Description + * Get Description. * * Returns validator description * @@ -52,35 +52,37 @@ class Authorization extends Validator } /** - * Is valid + * Is valid. * * Returns true if valid or false if not. * - * @param array $permissions + * @param array $permissions + * * @return bool */ public function isValid($permissions) { - if(!self::$status) { + if (!self::$status) { return true; } - if(!isset($permissions[$this->action])) { - $this->message = 'Missing action key: "' . $this->action . '"'; + if (!isset($permissions[$this->action])) { + $this->message = 'Missing action key: "'.$this->action.'"'; + return false; } $permission = null; foreach ($permissions[$this->action] as $permission) { - $permission = str_replace(':{self}', ':' . $this->document->getUid(), $permission); + $permission = str_replace(':{self}', ':'.$this->document->getUid(), $permission); - if(in_array($permission, self::getRoles())) { + if (in_array($permission, self::getRoles())) { return true; } } - $this->message = 'User is missing ' . $this->action . ' for ' . $permission . ' permission. only this scope "' . json_encode(self::getRoles()) . '" is given.'; + $this->message = 'User is missing '.$this->action.' for '.$permission.' permission. only this scope "'.json_encode(self::getRoles()).'" is given.'; return false; } @@ -88,7 +90,7 @@ class Authorization extends Validator /** * @param string $role */ - static public function setRole($role) + public static function setRole($role) { self::$roles[] = $role; } @@ -96,7 +98,7 @@ class Authorization extends Validator /** * @return array */ - static public function getRoles() + public static function getRoles() { return self::$roles; } @@ -104,12 +106,12 @@ class Authorization extends Validator /** * @var bool */ - static public $status = true; + public static $status = true; /** * */ - static public function enable() + public static function enable() { self::$status = true; } @@ -117,8 +119,8 @@ class Authorization extends Validator /** * */ - static public function disable() + public static function disable() { self::$status = false; } -} \ No newline at end of file +} diff --git a/src/Database/Validator/Collection.php b/src/Database/Validator/Collection.php index e5604d05e..40815ac06 100644 --- a/src/Database/Validator/Collection.php +++ b/src/Database/Validator/Collection.php @@ -19,7 +19,7 @@ class Collection extends Structure /** * @param Database $database - * @param array $collections + * @param array $collections */ public function __construct(Database $database, array $collections) { @@ -30,22 +30,25 @@ class Collection extends Structure /** * @param Document $document + * * @return bool */ public function isValid($document) { $document = (is_array($document)) ? new Document($document) : $document; - if(is_null($document->getCollection())) { + if (is_null($document->getCollection())) { $this->message = 'Missing collection attribute $collection'; + return false; } - if(!in_array($document->getCollection(), $this->collections)) { + if (!in_array($document->getCollection(), $this->collections)) { $this->message = 'Collection is not allowed'; + return false; } return parent::isValid($document); } -} \ No newline at end of file +} diff --git a/src/Database/Validator/Key.php b/src/Database/Validator/Key.php index 19c3416b9..cf266b115 100644 --- a/src/Database/Validator/Key.php +++ b/src/Database/Validator/Key.php @@ -12,7 +12,7 @@ class Key extends Validator protected $message = 'Parameter must contain only letters with no spaces or special chars and be shorter than 32 chars'; /** - * Get Description + * Get Description. * * Returns validator description * @@ -24,24 +24,24 @@ class Key extends Validator } /** - * Is valid + * Is valid. * * Returns true if valid or false if not. * * @param $value + * * @return bool */ public function isValid($value) { - if (preg_match('/[^A-Za-z0-9\-\_]/', $value)) - { + if (preg_match('/[^A-Za-z0-9\-\_]/', $value)) { return false; } - if(mb_strlen($value) > 40) { + if (mb_strlen($value) > 40) { return false; } return true; } -} \ No newline at end of file +} diff --git a/src/Database/Validator/Permissions.php b/src/Database/Validator/Permissions.php index 1273e1d9e..1dfc43aaa 100644 --- a/src/Database/Validator/Permissions.php +++ b/src/Database/Validator/Permissions.php @@ -28,7 +28,7 @@ class Permissions extends Validator } /** - * Get Description + * Get Description. * * Returns validator description * @@ -40,29 +40,33 @@ class Permissions extends Validator } /** - * Is valid + * Is valid. * * Returns true if valid or false if not. * * @param array $value + * * @return bool */ public function isValid($value) { - if(!is_array($value) && !empty($value)) { + if (!is_array($value) && !empty($value)) { $this->message = 'Invalid permissions data structure'; + return false; } foreach ($value as $action => $roles) { - if(!in_array($action, ['read', 'write'])) { - $this->message = 'Unknown action ("' . $action. '")'; + if (!in_array($action, ['read', 'write'])) { + $this->message = 'Unknown action ("'.$action.'")'; + return false; } foreach ($roles as $role) { - if(!is_string($role)) { + if (!is_string($role)) { $this->message = 'Permissions role must be a string'; + return false; } } @@ -70,4 +74,4 @@ class Permissions extends Validator return true; } -} \ No newline at end of file +} diff --git a/src/Database/Validator/Structure.php b/src/Database/Validator/Structure.php index e7df313cf..357c2be33 100644 --- a/src/Database/Validator/Structure.php +++ b/src/Database/Validator/Structure.php @@ -19,7 +19,7 @@ class Structure extends Validator protected $id = null; /** - * Basic rules to apply on all documents + * Basic rules to apply on all documents. * * @var array */ @@ -93,6 +93,7 @@ class Structure extends Validator /** * Structure constructor. + * * @param Database $database */ public function __construct(Database $database) @@ -101,7 +102,7 @@ class Structure extends Validator } /** - * Get Description + * Get Description. * * Returns validator description * @@ -109,15 +110,16 @@ class Structure extends Validator */ public function getDescription() { - return 'Invalid document (#' . $this->id . '): ' . $this->message; + return 'Invalid document (#'.$this->id.'): '.$this->message; } /** - * Is valid + * Is valid. * * Returns true if valid or false if not. * - * @param Document $document + * @param Document $document + * * @return bool */ public function isValid($document) @@ -126,36 +128,39 @@ class Structure extends Validator $this->id = $document->getUid(); - if(is_null($document->getCollection())) { + if (is_null($document->getCollection())) { $this->message = 'Missing collection attribute $collection'; + return false; } $collection = $this->getCollection($document->getCollection()); - if(is_null($collection->getUid()) || Database::SYSTEM_COLLECTION_COLLECTIONS != $collection->getCollection()) { + if (is_null($collection->getUid()) || Database::SYSTEM_COLLECTION_COLLECTIONS != $collection->getCollection()) { $this->message = 'Collection not found'; + return false; } - $array = $document->getArrayCopy(); - $rules = array_merge($this->rules, $collection->getAttribute('rules', [])); + $array = $document->getArrayCopy(); + $rules = array_merge($this->rules, $collection->getAttribute('rules', [])); foreach ($rules as $rule) { // Check all required keys are set - if(isset($rule['key']) && !isset($array[$rule['key']]) + if (isset($rule['key']) && !isset($array[$rule['key']]) && isset($rule['required']) && true == $rule['required']) { - $this->message = 'Missing required key "' . $rule['key'] . '"'; + $this->message = 'Missing required key "'.$rule['key'].'"'; + return false; } } foreach ($array as $key => $value) { - $rule = $collection->search('key', $key, $rules); - $ruleType = (isset($rule['type'])) ? $rule['type'] : ''; - $ruleOptions = (isset($rule['options'])) ? $rule['options'] : ''; - $ruleRequired = (isset($rule['required'])) ? $rule['required'] : true; - $ruleArray = (isset($rule['array'])) ? $rule['array'] : false; - $validator = null; + $rule = $collection->search('key', $key, $rules); + $ruleType = (isset($rule['type'])) ? $rule['type'] : ''; + $ruleOptions = (isset($rule['options'])) ? $rule['options'] : ''; + $ruleRequired = (isset($rule['required'])) ? $rule['required'] : true; + $ruleArray = (isset($rule['array'])) ? $rule['array'] : false; + $validator = null; switch ($ruleType) { case 'uid': @@ -194,42 +199,46 @@ class Structure extends Validator break; } - if(empty($validator)) { // Error creating validator for property - $this->message = 'Unknown property "' . $key . '"' . - '. Make sure to follow ' . strtolower($collection->getAttribute('name', 'unknown')) . ' collection structure'; + if (empty($validator)) { // Error creating validator for property + $this->message = 'Unknown property "'.$key.'"'. + '. Make sure to follow '.strtolower($collection->getAttribute('name', 'unknown')).' collection structure'; + return false; } - if($ruleRequired && ('' === $value || null === $value)) { - $this->message = 'Required property "' . $key . '" has no value'; + if ($ruleRequired && ('' === $value || null === $value)) { + $this->message = 'Required property "'.$key.'" has no value'; + return false; } - if(!$ruleRequired && empty($value)) { + if (!$ruleRequired && empty($value)) { unset($array[$key]); unset($rule); continue; } - if($ruleArray) { // Array of values validation - if(!is_array($value)) { - $this->message = 'Property "' . $key . '" must be an array'; + if ($ruleArray) { // Array of values validation + if (!is_array($value)) { + $this->message = 'Property "'.$key.'" must be an array'; + return false; } // TODO add is required check here foreach ($value as $node) { - if(!$validator->isValid($node)) { // Check if property is valid, if not required can also be empty - $this->message = 'Property "' . $key . '" has invalid input. ' . $validator->getDescription(); + if (!$validator->isValid($node)) { // Check if property is valid, if not required can also be empty + $this->message = 'Property "'.$key.'" has invalid input. '.$validator->getDescription(); + return false; } } - } - else { // Single value validation - if((!$validator->isValid($value)) && !('' === $value && !$ruleRequired)) { // Error when value is not valid, and is not optional and empty - $this->message = 'Property "' . $key . '" has invalid input. ' . $validator->getDescription(); + } else { // Single value validation + if ((!$validator->isValid($value)) && !('' === $value && !$ruleRequired)) { // Error when value is not valid, and is not optional and empty + $this->message = 'Property "'.$key.'" has invalid input. '.$validator->getDescription(); + return false; } } @@ -238,9 +247,10 @@ class Structure extends Validator unset($rule); } - if(!empty($array)) { // No fields should be left unvalidated - $this->message = 'Unknown properties are not allowed (' . implode(', ', array_keys($array)) . ') for this collection' . - '. Make sure to follow ' . strtolower($collection->getAttribute('name', 'unknown')) . ' collection structure'; + if (!empty($array)) { // No fields should be left unvalidated + $this->message = 'Unknown properties are not allowed ('.implode(', ', array_keys($array)).') for this collection'. + '. Make sure to follow '.strtolower($collection->getAttribute('name', 'unknown')).' collection structure'; + return false; } @@ -251,4 +261,4 @@ class Structure extends Validator { return $this->database->getDocument($uid); } -} \ No newline at end of file +} diff --git a/src/Database/Validator/UID.php b/src/Database/Validator/UID.php index b79d5c579..7c132ac35 100644 --- a/src/Database/Validator/UID.php +++ b/src/Database/Validator/UID.php @@ -7,7 +7,7 @@ use Utopia\Validator; class UID extends Validator { /** - * Get Description + * Get Description. * * Returns validator description * @@ -19,19 +19,20 @@ class UID extends Validator } /** - * Is valid + * Is valid. * * Returns true if valid or false if not. * - * @param string $value + * @param string $value + * * @return bool */ public function isValid($value) { - if(is_numeric($value)) { + if (is_numeric($value)) { //return false; } return true; } -} \ No newline at end of file +} diff --git a/src/Event/Event.php b/src/Event/Event.php index c155bfba6..42fad1edd 100644 --- a/src/Event/Event.php +++ b/src/Event/Event.php @@ -23,6 +23,7 @@ class Event /** * Event constructor. + * * @param string $queue * @param string $class */ @@ -34,17 +35,20 @@ class Event /** * @param string $key - * @param mixed $value + * @param mixed $value + * * @return $this */ public function setParam($key, $value) { $this->params[$key] = $value; + return $this; } /** * @param string $key + * * @return mixed|null */ public function getParam($key) @@ -53,10 +57,10 @@ class Event } /** - * Execute Event + * Execute Event. */ public function trigger() { Resque::enqueue($this->queue, $this->class, $this->params); } -} \ No newline at end of file +} diff --git a/src/OpenSSL/OpenSSL.php b/src/OpenSSL/OpenSSL.php index 0e264debd..73e1d4427 100644 --- a/src/OpenSSL/OpenSSL.php +++ b/src/OpenSSL/OpenSSL.php @@ -10,38 +10,41 @@ class OpenSSL * @param $data * @param $method * @param $key - * @param int $options + * @param int $options * @param string $iv - * @param null $tag + * @param null $tag * @param string $aad - * @param int $tag_length + * @param int $tag_length + * * @return string */ - static public function encrypt($data, $method, $key, $options = 0, $iv = '', &$tag = null, $aad = '', $tag_length = 16) + public static function encrypt($data, $method, $key, $options = 0, $iv = '', &$tag = null, $aad = '', $tag_length = 16) { - return openssl_encrypt($data, $method, $key, $options, $iv,$tag, $aad, $tag_length); + return openssl_encrypt($data, $method, $key, $options, $iv, $tag, $aad, $tag_length); } /** * @param $data * @param $method * @param $password - * @param int $options + * @param int $options * @param string $iv * @param string $tag * @param string $aad + * * @return string */ - static public function decrypt($data, $method, $password, $options = 1, $iv = '', $tag = '', $aad = '') + public static function decrypt($data, $method, $password, $options = 1, $iv = '', $tag = '', $aad = '') { return openssl_decrypt($data, $method, $password, $options, $iv, $tag, $aad); } /** * @param string $method + * * @return int */ - static public function cipherIVLength($method) + public static function cipherIVLength($method) { return openssl_cipher_iv_length($method); } @@ -49,10 +52,11 @@ class OpenSSL /** * @param $length * @param null $crypto_strong + * * @return int */ - static public function randomPseudoBytes($length, &$crypto_strong = null) + public static function randomPseudoBytes($length, &$crypto_strong = null) { return openssl_random_pseudo_bytes($length, $crypto_strong); } -} \ No newline at end of file +} diff --git a/src/Resize/Resize.php b/src/Resize/Resize.php index 0b55c7ffc..a56d3688d 100755 --- a/src/Resize/Resize.php +++ b/src/Resize/Resize.php @@ -15,39 +15,42 @@ class Resize /** * @param string $data + * * @throws Exception */ public function __construct($data) { - $this->image = new Imagick(); + $this->image = new Imagick(); $this->image->readImageBlob($data); - $this->width = $this->image->getImageWidth(); + $this->width = $this->image->getImageWidth(); $this->height = $this->image->getImageHeight(); } /** * @param int $width * @param int $height + * * @return Resize + * * @throws \ImagickException */ public function crop(int $width, int $height) { $originalAspect = $this->width / $this->height; - if(empty($width)) { + if (empty($width)) { $width = $height * $originalAspect; } - if(empty($height)) { + if (empty($height)) { $height = $width / $originalAspect; } - if(empty($height) && empty($width)) { + if (empty($height) && empty($width)) { $height = $this->height; - $width = $this->width; + $width = $this->width; } if ($this->image->getImageFormat() == 'GIF') { @@ -58,8 +61,7 @@ class Resize } $this->image->deconstructImages(); - } - else { + } else { $this->image->cropThumbnailImage($width, $height); } @@ -68,10 +70,13 @@ class Resize /** * @param $color + * * @return Resize + * * @throws \ImagickException */ - public function setBackground($color) { + public function setBackground($color) + { $this->image->setImageBackgroundColor($color); $this->image = $this->image->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN); @@ -79,13 +84,15 @@ class Resize } /** - * Output + * Output. * * Prints manipulated image. * * @param string $type - * @param int $quality + * @param int $quality + * * @return string + * * @throws Exception */ public function output(string $type, int $quality = 75) @@ -97,7 +104,9 @@ class Resize * @param string $path * @param $type * @param int $quality + * * @return string + * * @throws Exception */ public function save(string $path = null, string $type = '', int $quality = 75) @@ -122,9 +131,9 @@ class Resize case 'webp': //$this->image->setImageFormat('webp'); - $signature = $this->image->getImageSignature(); - $temp = '/tmp/temp-' . $signature . '.' . strtolower($this->image->getImageFormat()); - $output = '/tmp/output-' . $signature . '.webp'; + $signature = $this->image->getImageSignature(); + $temp = '/tmp/temp-'.$signature.'.'.strtolower($this->image->getImageFormat()); + $output = '/tmp/output-'.$signature.'.webp'; // save temp $this->image->writeImages($temp, true); @@ -135,10 +144,9 @@ class Resize $data = file_get_contents($output); //load webp - if(empty($path)) { + if (empty($path)) { return $data; - } - else { + } else { file_put_contents($path, $data, LOCK_EX); } @@ -149,20 +157,20 @@ class Resize unlink($output); unlink($temp); - return null; + return; break; case 'png': /* Scale quality from 0-100 to 0-9 */ - $scaleQuality = round(($quality/100) * 9); + $scaleQuality = round(($quality / 100) * 9); /* Invert quality setting as 0 is best, not 9 */ $invertScaleQuality = 9 - $scaleQuality; $this->image->setImageCompressionQuality($invertScaleQuality); - $this->image->setImageFormat("png"); + $this->image->setImageFormat('png'); break; default: @@ -170,10 +178,9 @@ class Resize break; } - if(empty($path)) { + if (empty($path)) { return $this->image->getImagesBlob(); - } - else { + } else { $this->image->writeImages($path, true); } @@ -182,7 +189,8 @@ class Resize } /** - * @param int $newHeight + * @param int $newHeight + * * @return int */ protected function getSizeByFixedHeight(int $newHeight):int @@ -194,7 +202,8 @@ class Resize } /** - * @param int $newWidth + * @param int $newWidth + * * @return int */ protected function getSizeByFixedWidth(int $newWidth):int @@ -204,4 +213,4 @@ class Resize return $newHeight; } -} \ No newline at end of file +} diff --git a/src/Storage/Compression/Algorithms/GZIP.php b/src/Storage/Compression/Algorithms/GZIP.php index ec2d28092..04dddfb35 100644 --- a/src/Storage/Compression/Algorithms/GZIP.php +++ b/src/Storage/Compression/Algorithms/GZIP.php @@ -15,7 +15,7 @@ class GZIP extends Compression } /** - * Compress + * Compress. * * We use gzencode over gzcompress for better support of the first format among other tools. * (http://stackoverflow.com/a/621987/2299554) @@ -23,6 +23,7 @@ class GZIP extends Compression * @see http://php.net/manual/en/function.gzencode.php * * @param string $data + * * @return string */ public function compress(string $data):string @@ -31,13 +32,14 @@ class GZIP extends Compression } /** - * Decompress + * Decompress. * * @param string $data + * * @return string */ public function decompress(string $data):string { return gzdecode($data); } -} \ No newline at end of file +} diff --git a/src/Storage/Compression/Compression.php b/src/Storage/Compression/Compression.php index 11c5f99eb..87a70d521 100644 --- a/src/Storage/Compression/Compression.php +++ b/src/Storage/Compression/Compression.php @@ -5,7 +5,7 @@ namespace Storage\Compression; abstract class Compression { /** - * Return the name of compression algorithm + * Return the name of compression algorithm. * * @return string */ @@ -13,13 +13,15 @@ abstract class Compression /** * @param $data + * * @return string */ abstract public function compress(string $data); /** * @param $data + * * @return string */ abstract public function decompress(string $data); -} \ No newline at end of file +} diff --git a/src/Storage/Device.php b/src/Storage/Device.php index e405c3791..8fab1b41f 100644 --- a/src/Storage/Device.php +++ b/src/Storage/Device.php @@ -7,7 +7,7 @@ use Exception; abstract class Device { /** - * Get Name + * Get Name. * * Get storage device name * @@ -16,7 +16,7 @@ abstract class Device abstract public function getName(); /** - * Get Description + * Get Description. * * Get storage device description and purpose. * @@ -25,7 +25,7 @@ abstract class Device abstract public function getDescription(); /** - * Get Root + * Get Root. * * Get storage device root path * @@ -34,42 +34,45 @@ abstract class Device abstract public function getRoot(); /** - * Get Path + * Get Path. * * Each device hold a complex directory structure that is being build in this method. * * @param $filename + * * @return string */ public function getPath($filename) { - return $this->getRoot() . DIRECTORY_SEPARATOR . $filename; + return $this->getRoot().DIRECTORY_SEPARATOR.$filename; } /** - * Upload + * Upload. * * Upload a file to desired destination in the selected disk. * - * @param string $target - * @param string $filename + * @param string $target + * @param string $filename + * * @throws \Exception + * * @return string|bool saved destination on success or false on failures */ public function upload($target, $filename = '') { - $filename = (empty($filename)) ? $target : $filename; - $filename = uniqid() . '.' . pathinfo($filename, PATHINFO_EXTENSION); + $filename = (empty($filename)) ? $target : $filename; + $filename = uniqid().'.'.pathinfo($filename, PATHINFO_EXTENSION); - $path = $this->getPath($filename); + $path = $this->getPath($filename); - if(!is_uploaded_file($target)) { + if (!is_uploaded_file($target)) { throw new Exception('File is not a valid uploaded file'); } if (!file_exists(dirname($path))) { // Checks if directory path to file exists - if(!mkdir(dirname($path), 0755, true)) { - throw new Exception('Can\'t create directory ' . dirname($path)); + if (!mkdir(dirname($path), 0755, true)) { + throw new Exception('Can\'t create directory '.dirname($path)); } } @@ -81,9 +84,10 @@ abstract class Device } /** - * Read file by given path + * Read file by given path. * * @param string $path + * * @return string */ public function read(string $path):string @@ -92,10 +96,11 @@ abstract class Device } /** - * Write file by given path + * Write file by given path. * * @param string $path * @param string $data + * * @return string */ public function write(string $path, string $data):bool @@ -104,11 +109,12 @@ abstract class Device } /** - * Delete file in given path, Return true on success and false on failure + * Delete file in given path, Return true on success and false on failure. * * @see http://php.net/manual/en/function.filesize.php * * @param string $path + * * @return bool */ public function delete(string $path):bool @@ -117,37 +123,38 @@ abstract class Device } /** - * Delete all file and directories in given path, Return true on success and false on failure + * Delete all file and directories in given path, Return true on success and false on failure. * * @see https://paulund.co.uk/php-delete-directory-and-files-in-directory * * @param string $path + * * @return bool */ public function deleteDir($target):bool { if (is_dir($target)) { - $files = glob($target . '*', GLOB_MARK); // GLOB_MARK adds a slash to directories returned - + $files = glob($target.'*', GLOB_MARK); // GLOB_MARK adds a slash to directories returned + foreach ($files as $file) { - $this->deleteDir($file); + $this->deleteDir($file); } - + rmdir($target); - } - elseif (is_file($target)) { - unlink( $target ); + } elseif (is_file($target)) { + unlink($target); } return true; } /** - * Returns given file path its size + * Returns given file path its size. * * @see http://php.net/manual/en/function.filesize.php * * @param $path + * * @return int */ public function getFileSize(string $path):int @@ -156,11 +163,12 @@ abstract class Device } /** - * Returns given file path its mime type + * Returns given file path its mime type. * * @see http://php.net/manual/en/function.mime-content-type.php * * @param $path + * * @return string */ public function getFileMimeType(string $path):string @@ -169,11 +177,12 @@ abstract class Device } /** - * Returns given file path its MD5 hash value + * Returns given file path its MD5 hash value. * * @see http://php.net/manual/en/function.md5-file.php * * @param $path + * * @return string */ public function getFileHash(string $path):string @@ -182,13 +191,14 @@ abstract class Device } /** - * Get directory size in bytes + * Get directory size in bytes. * * Return -1 on error * * Based on http://www.jonasjohn.de/snippets/php/dir-size.htm * * @param $path + * * @return int */ public function getDirectorySize(string $path):int @@ -197,19 +207,21 @@ abstract class Device $directory = opendir($path); - if (!$directory) + if (!$directory) { return -1; + } while (($file = readdir($directory)) !== false) { // Skip file pointers - if ($file[0] == '.') continue; + if ($file[0] == '.') { + continue; + } // Go recursive down, or add the file size - if (is_dir($path . $file)) { - $size += $this->getDirectorySize($path . $file . DIRECTORY_SEPARATOR); - } - else { - $size += filesize($path . $file); + if (is_dir($path.$file)) { + $size += $this->getDirectorySize($path.$file.DIRECTORY_SEPARATOR); + } else { + $size += filesize($path.$file); } } @@ -219,7 +231,7 @@ abstract class Device } /** - * Get Partition Free Space + * Get Partition Free Space. * * disk_free_space — Returns available space on filesystem or disk partition * @@ -231,7 +243,7 @@ abstract class Device } /** - * Get Partition Total Space + * Get Partition Total Space. * * disk_total_space — Returns the total size of a filesystem or disk partition * @@ -243,25 +255,26 @@ abstract class Device } /** - * Human readable data size format from bytes input + * Human readable data size format from bytes input. * * As published on https://gist.github.com/liunian/9338301 (first comment) * * @param int $bytes * @param int $decimals + * * @return string */ public function human($bytes, $decimals = 2) { - $units = array('B','kB','MB','GB','TB','PB','EB','ZB','YB'); - $step = 1024; - $i = 0; + $units = array('B','kB','MB','GB','TB','PB','EB','ZB','YB'); + $step = 1024; + $i = 0; while (($bytes / $step) > 0.9) { $bytes = $bytes / $step; - $i++; + ++$i; } - return round($bytes, $decimals) . $units[$i]; + return round($bytes, $decimals).$units[$i]; } -} \ No newline at end of file +} diff --git a/src/Storage/Devices/Local.php b/src/Storage/Devices/Local.php index 11e83ae6c..384c613fb 100644 --- a/src/Storage/Devices/Local.php +++ b/src/Storage/Devices/Local.php @@ -13,6 +13,7 @@ class Local extends Device /** * Local constructor. + * * @param string $root */ public function __construct($root = '') @@ -41,21 +42,22 @@ class Local extends Device */ public function getRoot() { - return '/storage/uploads/' . $this->root; + return '/storage/uploads/'.$this->root; } /** * @param string $filename + * * @return string */ public function getPath($filename) { $path = ''; - for ($i = 0; $i < 4; $i++) { - $path = ($i < strlen($filename)) ? $path . DIRECTORY_SEPARATOR . $filename[$i] : $path . DIRECTORY_SEPARATOR . 'x'; + for ($i = 0; $i < 4; ++$i) { + $path = ($i < strlen($filename)) ? $path.DIRECTORY_SEPARATOR.$filename[$i] : $path.DIRECTORY_SEPARATOR.'x'; } - return $this->getRoot() . $path . DIRECTORY_SEPARATOR . $filename; + return $this->getRoot().$path.DIRECTORY_SEPARATOR.$filename; } -} \ No newline at end of file +} diff --git a/src/Storage/Devices/S3.php b/src/Storage/Devices/S3.php index 0757c969d..5880a8d38 100644 --- a/src/Storage/Devices/S3.php +++ b/src/Storage/Devices/S3.php @@ -32,16 +32,17 @@ class S3 extends Device /** * @param string $filename + * * @return string */ public function getPath($filename) { $path = ''; - for ($i = 0; $i < 4; $i++) { - $path = ($i < strlen($filename)) ? $path . DIRECTORY_SEPARATOR . $filename[$i] : $path . DIRECTORY_SEPARATOR . 'x'; + for ($i = 0; $i < 4; ++$i) { + $path = ($i < strlen($filename)) ? $path.DIRECTORY_SEPARATOR.$filename[$i] : $path.DIRECTORY_SEPARATOR.'x'; } - return $this->getRoot() . $path . DIRECTORY_SEPARATOR . $filename; + return $this->getRoot().$path.DIRECTORY_SEPARATOR.$filename; } -} \ No newline at end of file +} diff --git a/src/Storage/Storage.php b/src/Storage/Storage.php index a56e6adba..b5a7b9f30 100644 --- a/src/Storage/Storage.php +++ b/src/Storage/Storage.php @@ -7,60 +7,64 @@ use Exception; class Storage { /** - * Devices + * Devices. * * List of all available storage devices * * @var array */ - static $devices = array(); + public static $devices = array(); /** - * Add Device + * Add Device. * * Add device by name * * @param string $name * @param Device $device + * * @throws Exception */ - static public function addDevice($name, Device $device) + public static function addDevice($name, Device $device) { - if(array_key_exists($name, self::$devices)) { - throw new Exception('The device "' . $name . '" is already listed'); + if (array_key_exists($name, self::$devices)) { + throw new Exception('The device "'.$name.'" is already listed'); } self::$devices[$name] = $device; } /** - * Get Device + * Get Device. * * Get device by name * * @param string $name + * * @return Device + * * @throws Exception */ - static public function getDevice($name) + public static function getDevice($name) { - if(!array_key_exists($name, self::$devices)) { - throw new Exception('The device "' . $name . '" is not listed'); + if (!array_key_exists($name, self::$devices)) { + throw new Exception('The device "'.$name.'" is not listed'); } return self::$devices[$name]; } /** - * Exists + * Exists. * * Checks if given storage name is registered or not * * @param string $name + * * @return bool */ - static public function exists($name) + public static function exists($name) { - return (bool)array_key_exists($name, self::$devices); + return (bool) array_key_exists($name, self::$devices); } } diff --git a/src/Storage/Validators/File.php b/src/Storage/Validators/File.php index 7d9d6c534..248c41040 100644 --- a/src/Storage/Validators/File.php +++ b/src/Storage/Validators/File.php @@ -6,18 +6,18 @@ use Utopia\Validator; class File extends Validator { - public function getDescription() { return 'File is not valid'; } /** - * NOT MUCH RIGHT NOW + * NOT MUCH RIGHT NOW. * * TODO think what to do here, currently only used for parameter to be present in SDKs * - * @param string $name + * @param string $name + * * @return bool */ public function isValid($name) diff --git a/src/Storage/Validators/FileName.php b/src/Storage/Validators/FileName.php index 29d82590e..62236b122 100644 --- a/src/Storage/Validators/FileName.php +++ b/src/Storage/Validators/FileName.php @@ -6,25 +6,25 @@ use Utopia\Validator; class FileName extends Validator { - public function getDescription() { return 'Filename is not valid'; } /** - * The file name can only contain "a-z", "A-Z", "0-9" and "-" and not empty + * The file name can only contain "a-z", "A-Z", "0-9" and "-" and not empty. + * + * @param string $name * - * @param string $name * @return bool */ public function isValid($name) { - if(empty($name)) { + if (empty($name)) { return false; } - if(!preg_match('/^[a-zA-Z0-9.]+$/', $name)) { + if (!preg_match('/^[a-zA-Z0-9.]+$/', $name)) { return false; } diff --git a/src/Storage/Validators/FileSize.php b/src/Storage/Validators/FileSize.php index 713528071..7cc5b776a 100644 --- a/src/Storage/Validators/FileSize.php +++ b/src/Storage/Validators/FileSize.php @@ -21,13 +21,14 @@ class FileSize extends Validator public function getDescription() { - return 'File size can\'t be bigger than ' . $this->max; + return 'File size can\'t be bigger than '.$this->max; } /** - * Finds whether a file size is smaller than required limit + * Finds whether a file size is smaller than required limit. + * + * @param int $fileSize * - * @param int $fileSize * @return bool */ public function isValid($fileSize) diff --git a/src/Storage/Validators/FileType.php b/src/Storage/Validators/FileType.php index ba10a7bac..0f1870e70 100644 --- a/src/Storage/Validators/FileType.php +++ b/src/Storage/Validators/FileType.php @@ -8,21 +8,21 @@ use Utopia\Validator; class FileType extends Validator { /** - * File Types Constants + * File Types Constants. */ - const FILE_TYPE_JPEG = 'jpeg'; - const FILE_TYPE_GIF = 'gif'; - const FILE_TYPE_PNG = 'png'; + const FILE_TYPE_JPEG = 'jpeg'; + const FILE_TYPE_GIF = 'gif'; + const FILE_TYPE_PNG = 'png'; /** - * File Type Binaries + * File Type Binaries. * * @var array */ protected $types = array( - self::FILE_TYPE_JPEG => "\xFF\xD8\xFF", - self::FILE_TYPE_GIF => 'GIF', - self::FILE_TYPE_PNG => "\x89\x50\x4e\x47\x0d\x0a", + self::FILE_TYPE_JPEG => "\xFF\xD8\xFF", + self::FILE_TYPE_GIF => 'GIF', + self::FILE_TYPE_PNG => "\x89\x50\x4e\x47\x0d\x0a", ); /** @@ -31,7 +31,8 @@ class FileType extends Validator protected $whiteList; /** - * @param array $whiteList + * @param array $whiteList + * * @throws Exception */ public function __construct(array $whiteList) @@ -51,12 +52,14 @@ class FileType extends Validator } /** - * Is Valid + * Is Valid. * * Binary check to finds whether a file is of valid type * * @see http://stackoverflow.com/a/3313196 - * @param string $path + * + * @param string $path + * * @return bool */ public function isValid($path) diff --git a/src/Task/Validator/Cron.php b/src/Task/Validator/Cron.php index e050eefae..927f46e43 100644 --- a/src/Task/Validator/Cron.php +++ b/src/Task/Validator/Cron.php @@ -7,9 +7,8 @@ use Utopia\Validator; class Cron extends Validator { - /** - * Get Description + * Get Description. * * Returns validator description * @@ -21,19 +20,20 @@ class Cron extends Validator } /** - * Is valid + * Is valid. * * Returns true if valid or false if not. * - * @param mixed $value + * @param mixed $value + * * @return bool */ public function isValid($value) { - if(!CronExpression::isValidExpression($value)) { + if (!CronExpression::isValidExpression($value)) { return false; } return true; } -} \ No newline at end of file +} diff --git a/src/Template/Template.php b/src/Template/Template.php index b15880dfd..94a622abe 100644 --- a/src/Template/Template.php +++ b/src/Template/Template.php @@ -8,12 +8,13 @@ use Utopia\View; class Template extends View { /** - * Render + * Render. * * Render view .phtml template file if template has not been set as rendered yet using $this->setRendered(true). * In case path is not readable throws Exception. * * @return string + * * @throws Exception */ public function render() @@ -24,9 +25,8 @@ class Template extends View if (is_readable($this->path)) { $template = file_get_contents($this->path); // Include template file - } - else { - throw new Exception('"' . $this->path . '" template is not readable or not found'); + } else { + throw new Exception('"'.$this->path.'" template is not readable or not found'); } $template = str_replace(array_keys($this->params), array_values($this->params), $template); @@ -35,54 +35,57 @@ class Template extends View } /** - * Parse URL + * Parse URL. * * Parse URL string to array * * @param $url + * * @return mixed On seriously malformed URLs, parse_url() may return FALSE. */ - static public function parseURL($url) + public static function parseURL($url) { return parse_url($url); } /** - * Un-Parse URL + * Un-Parse URL. * * Convert PHP array to query string * * @param $url + * * @return string */ - static public function unParseURL(array $url) + public static function unParseURL(array $url) { - $scheme = isset($url['scheme']) ? $url['scheme'] . '://' : ''; - $host = isset($url['host']) ? $url['host'] : ''; - $port = isset($url['port']) ? ':' . $url['port'] : ''; + $scheme = isset($url['scheme']) ? $url['scheme'].'://' : ''; + $host = isset($url['host']) ? $url['host'] : ''; + $port = isset($url['port']) ? ':'.$url['port'] : ''; - $user = isset($url['user']) ? $url['user'] : ''; - $pass = isset($url['pass']) ? ':' . $url['pass'] : ''; - $pass = ($user || $pass) ? "$pass@" : ''; + $user = isset($url['user']) ? $url['user'] : ''; + $pass = isset($url['pass']) ? ':'.$url['pass'] : ''; + $pass = ($user || $pass) ? "$pass@" : ''; - $path = isset($url['path']) ? $url['path'] : ''; - $query = isset($url['query']) && !empty($url['query']) ? '?' . $url['query'] : ''; + $path = isset($url['path']) ? $url['path'] : ''; + $query = isset($url['query']) && !empty($url['query']) ? '?'.$url['query'] : ''; - $fragment = isset($url['fragment']) ? '#' . $url['fragment'] : ''; + $fragment = isset($url['fragment']) ? '#'.$url['fragment'] : ''; - return $scheme . $user . $pass . $host . $port . $path . $query . $fragment; + return $scheme.$user.$pass.$host.$port.$path.$query.$fragment; } /** - * Merge Query + * Merge Query. * * Merge array of params to query string * * @param $query1 * @param array $query2 + * * @return string */ - static public function mergeQuery($query1, array $query2) + public static function mergeQuery($query1, array $query2) { $parsed = []; @@ -92,4 +95,4 @@ class Template extends View return http_build_query($parsed); } -} \ No newline at end of file +}