Skip to content

Commit

Permalink
Merge pull request #93 from juvenn/master
Browse files Browse the repository at this point in the history
Merge from v0.2 branch
  • Loading branch information
juvenn committed May 17, 2016
2 parents b3c23a7 + bd30b84 commit c8cd54f
Show file tree
Hide file tree
Showing 14 changed files with 231 additions and 72 deletions.
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ language: php

php:
- 5.3
- 5.4
- 5.5
- 5.6
- 7.0

env:
- LC_API_REGION=US
Expand Down
9 changes: 9 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@

0.2.6 发布日期:2016-05-16
----
* LeanPush 支持同时向多平台发送推送
* LeanObject::save, fetch, destroy 不再返回批量查询错误
* 修复 LeanACL 为空时被编码为 array 的问题
- LeanACL::encode 将返回 object (不兼容)
* 修复 LeanRole 查询不能正常初识化
- LeanRole 构造函数接收两个可选参数 className, objectId (不兼容)

0.2.5 发布日期:2016-02-01
----
* 支持手机号码和密码登录
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ use LeanCloud\LeanUser;
use LeanCloud\CloudException;

$user = new LeanUser();
$user->setUsername("alice"):
$user->setUsername("alice");
$user->setEmail("[email protected]");
$user->setPassword("passpass");
try {
Expand Down Expand Up @@ -228,7 +228,7 @@ try {
}
```

完整的 API 文档请参考: https://leancloud.cn/docs/api/php/
完整的 API 文档请参考: https://leancloud.cn/api-docs/php

贡献
----
Expand Down
85 changes: 85 additions & 0 deletions src/LeanCloud/BatchRequestError.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php
namespace LeanCloud;

/**
* BatchRequestError
*
* A BatchRequestError object consists of zero or more request and
* response errors.
*
*/
class BatchRequestError extends CloudException {

/**
* Array of error response
*
* @var array
*/
private $errors;

public function __construct($message="", $code = 1) {
$message = empty($message) ? "Batch request error." : $message;
parent::__construct($message, $code);
}

/**
* Add failed request and its error response
*
* Both request and response are expected to be array. The response
* array must contain an `error` message, while the request should
* contain `method` and `path`.
*
* @return BatchRequestError
*/
public function add($request, $response) {
if (!isset($response["error"])) {
throw new \InvalidArgumentException("Invalid error response.");
}
if (!isset($response["code"])) {
$response["code"] = 1;
}
$response["request"] = $request;
$this->errors[] = $response;
return $this;
}

/**
* Get all error response
*
* @return array
*/
public function getAll() {
return $this->errors;
}

/**
* Get first error response as map
*
* Returns associative array of following format:
*
* `{"code": 101, "error": "error message", "request": {...}}`
*
* @return array|null
*/
public function getFirst() {
return isset($this->errors[0]) ? $this->errors[0] : null;
}

/**
* Contains error response or not
*
* @return bool
*/
public function isEmpty() {
return count($this->errors) == 0;
}

public function __toString() {
$message = $this->message;
if (!$this->isEmpty()) {
$message .= json_encode($this-errors);
}
return __CLASS__ . ": [{$this->code}]: {$message}\n";
}
}

22 changes: 14 additions & 8 deletions src/LeanCloud/LeanACL.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,27 +31,29 @@ class LeanACL {
* user will be granted both read and write access. While the
* latter will be interpretted as JSON encoded array.
*
* With empty param, it creates an ACL with no permission granted.
*
* @param mixed $val LeanUser or JSON encoded ACL array
*/
public function __construct($val=null) {
public function __construct($val=array()) {
$this->data = array();

if (!isset($val)) { return; }

if ($val instanceof LeanUser) {
$this->setReadAccess($val, true);
$this->setWriteAccess($val, true);
} else if (is_array($val)) {
forEach($val as $id => $attr) {
if (!is_string($id)) {
throw new \RuntimeException("Invalid ACL data");
throw new \RuntimeException("Invalid ACL target");
}
if (isset($attr["read"]) || isset($attr["write"])) {
$this->data[$id] = $attr;
} else {
throw new \RuntimeException("Invalid ACL data");
throw new \RuntimeException("Invalid ACL access type");
}
}
} else {
throw new \RuntimeException("Invalid ACL data.");
}
}

Expand All @@ -65,7 +67,7 @@ public function __construct($val=null) {
*/
private function setAccess($target, $accessType, $flag) {
if (empty($target)) {
throw new \InvalidArgumentException("Access target cannot be empty");
throw new \InvalidArgumentException("ACL target cannot be empty");
}
if (!in_array($accessType, array("read", "write"))) {
throw new \InvalidArgumentException("ACL access type must be" .
Expand Down Expand Up @@ -296,10 +298,14 @@ public function setWriteAccess($user, $flag) {
/**
* Encode to JSON representation
*
* @return array
* It returns an associative array, or an empty object if
* empty. The latter is a workaround as we need to json encode
* empty ACL as json object, instead of array.
*
* @return array|object
*/
public function encode() {
return $this->data;
return empty($this->data) ? new \stdClass() : $this->data;
}
}

16 changes: 12 additions & 4 deletions src/LeanCloud/LeanClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class LeanClient {
/**
* Client version
*/
const VERSION = '0.2.5';
const VERSION = '0.2.6';

/**
* API Endpoints for Regions
Expand Down Expand Up @@ -464,10 +464,18 @@ public static function batch($requests, $sessionToken=null,
$sessionToken,
$headers,
$useMasterKey);
if (count($requests) != count($response)) {
throw new CloudException("Number of resquest and response " .
"mismatch in batch operation!");

$batchRequestError = new BatchRequestError();
forEach($requests as $i => $req) {
if (isset($response[$i]["error"])) {
$batchRequestError->add($req, $response[$i]["error"]);
}
}

if (!$batchRequestError->isEmpty()) {
throw $batchRequestError;
}

return $response;
}

Expand Down
64 changes: 29 additions & 35 deletions src/LeanCloud/LeanObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -386,11 +386,18 @@ private function getSaveData() {
/**
* Save object and its children objects and files
*
* @throws RuntimeException
* @throws CloudException
*/
public function save() {
if (!$this->isDirty()) {return;}
return self::saveAll(array($this));
try {
$result = self::saveAll(array($this));
} catch (BatchRequestError $batchRequestError) {
$err = $batchRequestError->getFirst();
if ($err)
throw new CloudException($err["error"], $err["code"]);
}
return $result;
}

/**
Expand Down Expand Up @@ -451,7 +458,13 @@ public function mergeAfterFetch($data) {
* @throws RuntimeException, CloudException
*/
public function fetch() {
static::fetchAll(array($this));
try {
static::fetchAll(array($this));
} catch (BatchRequestError $batchRequestError) {
$err = $batchRequestError->getFirst();
if ($err)
throw new CloudException($err["error"], $err["code"]);
}
}

/**
Expand Down Expand Up @@ -485,23 +498,19 @@ public function fetchAll($objects) {
$sessionToken = LeanUser::getCurrentSessionToken();
$response = LeanClient::batch($requests, $sessionToken);

$errors = array();
$batchRequestError = new BatchRequestError();
forEach($objects as $i => $obj) {
if (isset($response[$i]["success"])) {
if (!empty($response[$i]["success"])) {
$obj->mergeAfterFetch($response[$i]["success"]);
} else {
$errors[] = array("request" => $requests[$i],
"error" => "Object not found.");
$batchRequestError->add($requests[$i],
array("error" => "Object not found."));
}
} else {
$errors[] = array("request" => $requests[$i],
"error" => $response[$i]["error"]);
}
}
if (count($errors) > 0) {
throw new CloudException("Batch requests error: " .
json_encode($errors));
if (!$batchRequestError->isEmpty()) {
throw $batchRequestError;
}
}

Expand All @@ -516,7 +525,14 @@ public function destroy() {
if (!$this->getObjectId()) {
return false;
}
return self::destroyAll(array($this));

try {
static::destroyAll(array($this));
} catch (BatchRequestError $batchRequestError) {
$err = $batchRequestError->getFirst();
if ($err)
throw new CloudException($err["error"], $err["code"]);
}
}

/**
Expand Down Expand Up @@ -679,21 +695,11 @@ private static function batchSave($objects, $batchSize=20) {
$sessionToken = LeanUser::getCurrentSessionToken();
$response = LeanClient::batch($requests, $sessionToken);

// TODO: append remaining unsaved items to errors, so user
// knows all objects that failed to save?
$errors = array();
forEach($objects as $i => $obj) {
if (isset($response[$i]["success"])) {
$obj->mergeAfterSave($response[$i]["success"]);
} else {
$errors[] = array("request" => $requests[$i],
"error" => $response[$i]["error"]);
}
}
if (count($errors) > 0) {
throw new CloudException("Batch requests error: " .
json_encode($errors));
}

// start next batch
static::batchSave($remaining, $batchSize);
Expand Down Expand Up @@ -728,18 +734,6 @@ public static function destroyAll($objects) {

$sessionToken = LeanUser::getCurrentSessionToken();
$response = LeanClient::batch($requests, $sessionToken);

$errors = array();
forEach($objects as $i => $obj) {
if (isset($response[$i]["error"])) {
$errors[] = array("request" => $requests[$i],
"error" => $response[$i]["error"]);
}
}
if (count($errors) > 0) {
throw new CloudException("Batch requests error: " .
json_encode($errors));
}
}
}

5 changes: 0 additions & 5 deletions src/LeanCloud/LeanPush.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,6 @@ public function setExpirationTime(\DateTime $time) {
* @return array
*/
public function encode() {
if (!isset($this->data["alert"])) {
throw new \RuntimeException("No `alert' message specified " .
"in notification data");
}

$out = $this->options;
$out["data"] = $this->data;
if (isset($this->options["where"])) {
Expand Down
10 changes: 4 additions & 6 deletions src/LeanCloud/LeanRole.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,16 @@ class LeanRole extends LeanObject {
protected static $className = "_Role";

/**
* Initialize a role
* Set name of role
*
* The name can contain only alphanumeric characters, _, -, and
* space. It cannot be changed after being saved.
*
* @param string $name The name of role
* @param LeanACL $acl The ACL specifies who can change **this role**
* @return LeanRole
*/
public function __construct($name, $acl) {
parent::__construct();
public function setName($name) {
$this->set("name", $name);
$this->setACL($acl);
return $this;
}

/**
Expand Down
Loading

0 comments on commit c8cd54f

Please sign in to comment.