From e65c46b730b92e344f75b033880928cc61503396 Mon Sep 17 00:00:00 2001 From: Zanderwar Date: Tue, 27 Dec 2016 19:02:42 +1000 Subject: [PATCH] API for Page Rule handling --- code/Rules/Items/Actions/RuleAction.php | 90 ++++++ code/Rules/Items/Actions/RuleActionList.php | 52 +++ code/Rules/Items/RuleItem.php | 332 ++++++++++++++++++++ code/Rules/Items/RuleItemList.php | 52 +++ code/Rules/Items/Targets/RuleTarget.php | 125 ++++++++ code/Rules/Items/Targets/RuleTargetList.php | 52 +++ code/Rules/RuleHandler.php | 104 ++++++ 7 files changed, 807 insertions(+) create mode 100644 code/Rules/Items/Actions/RuleAction.php create mode 100644 code/Rules/Items/Actions/RuleActionList.php create mode 100644 code/Rules/Items/RuleItem.php create mode 100644 code/Rules/Items/RuleItemList.php create mode 100644 code/Rules/Items/Targets/RuleTarget.php create mode 100644 code/Rules/Items/Targets/RuleTargetList.php create mode 100644 code/Rules/RuleHandler.php diff --git a/code/Rules/Items/Actions/RuleAction.php b/code/Rules/Items/Actions/RuleAction.php new file mode 100644 index 0000000..95f41b2 --- /dev/null +++ b/code/Rules/Items/Actions/RuleAction.php @@ -0,0 +1,90 @@ +actionId = $actionId; + + return $this; + } + + /** + * Gets the action id + * + * @return string + */ + public function getActionId() + { + return $this->actionId; + } + + /** + * Set the value for this objects action id + * + * @param int|string $value + * + * @return $this + */ + public function setValue($value) + { + $this->value = $value; + + return $this; + } + + /** + * Get the value of this objects action id + * + * @return int|string + */ + public function getValue() + { + return $this->value; + } + + /** + * Converts this object to an array in the format expected by CloudFlare + * + * @return array + */ + public function toArray() + { + return array( + 'id' => $this->getActionId(), + 'value' => $this->getValue() + ); + } + + /** + * Converts this object to a JSON string in the format expected by CloudFlare + * + * @return array + */ + public function toJson() { + return json_encode($this->toArray()); + } +} \ No newline at end of file diff --git a/code/Rules/Items/Actions/RuleActionList.php b/code/Rules/Items/Actions/RuleActionList.php new file mode 100644 index 0000000..d7a49a2 --- /dev/null +++ b/code/Rules/Items/Actions/RuleActionList.php @@ -0,0 +1,52 @@ +items)) { + return; + } + + $this->items[] = $item; + } + + /** + * Converts all children of this object into an array + * + * @return array + */ + public function toArray() + { + $stack = array(); + + foreach ($this->items as $item) { + $stack[] = $item->toArray(); + } + + return $stack; + } + + /** + * Converts all children of this object into an array and outputs it as JSON + * + * @return string + */ + public function toJson() + { + return json_encode($this->toArray()); + } +} \ No newline at end of file diff --git a/code/Rules/Items/RuleItem.php b/code/Rules/Items/RuleItem.php new file mode 100644 index 0000000..d190701 --- /dev/null +++ b/code/Rules/Items/RuleItem.php @@ -0,0 +1,332 @@ +push(RuleTarget::create() + ->setTarget($target['target']) + ->setOperator('matches') + ->setValue($target['constraint']['value']) + ); + } + + $actionList = RuleActionList::create(); + foreach ($source['actions'] as $action) { + $actionList->push(RuleAction::create() + ->setActionId($action['id']) + ->setValue($action['value']) + ); + } + + $this->identifier = $source['id']; + $this->targets = $targetList; + $this->actions = $actionList; + $this->priority = $source['priority']; + $this->status = ($source['status'] == 'active'); + $this->createdOn = $source['created_on']; + $this->modifiedOn = $source['modified_on']; + + return $this; + } + + /** + * Used to update or create a new page rule, the difference is based on whether or not `$this->identifier` is set + * + * @return string|bool Returns the identifier on success + */ + public function save() + { + $data = $this->toArray(); + + unset($data['id']); // remove ID from data as if it exists; the endpoint is updated with it dynamically + + $json = CloudFlare::singleton()->curlRequest( + $this->getEndpoint(), + $data, + 'PUT' + ); + + $result = json_decode($json, true); + + if (!$result['success']) { + $this->hasError = true; + $this->errorMessage = $result['errors']; + + return false; + } + + $this->identifier = $result['result']['id']; + RuleHandler::flush(); + + return $this->identifier; + + } + + /** + * Delete the active page rule + * + * @return bool + */ + public function delete() + { + if (!$this->identifier) { + return true; + } + + $json = CloudFlare::singleton()->curlRequest($this->getEndpoint()); + $result = json_decode($json, true); + + if (!$result['success']) { + $this->hasError = true; + $this->errorMessage = $result['errors']; + + return false; + } + + unset($this->identifier); + RuleHandler::flush(); + + return true; + } + + /** + * Get the identifier for the active page rule + * @return string|null + */ + public function getIdentifier() + { + return $this->identifier; + } + + /** + * Gets the list of targets + * + * @return array|null + */ + public function getTargets() + { + return $this->targets; + } + + /** + * Sets the list of targets + * + * @param $targets + * + * @return $this + */ + public function setTargets($targets) + { + foreach ($targets as $target) { + if (!($target instanceof RuleTarget)) { + user_error('setTargets() only accepts an array of RuleTarget\'s, one of the values was of type ' . gettype($target), + E_USER_ERROR); + } + } + $this->targets = $targets; + + return $this; + } + + /** + * Gets the list of actions that is (or is tobe) placed against this page rule + * + * @return array An array of RuleAction's + */ + public function getActions() + { + return $this->actions; + } + + /** + * @param $actions + * + * @return $this + */ + public function setActions($actions) + { + foreach ($actions as $action) { + if (!($action instanceof RuleTarget)) { + user_error('setActions() only accepts an array of RuleTarget\'s, one of the values was of type ' . gettype($action), + E_USER_ERROR); + } + } + + $this->actions = $actions; + + return $this; + } + + /** + * Get priority + * + * @return int + */ + public function getPriority() + { + return $this->priority; + } + + /** + * Set Priority + * + * @param int $priority + * + * @return $this + */ + public function setPriority($priority) + { + $this->priority = $priority; + + return $this; + } + + /** + * Get Status + * + * @return bool + */ + public function getStatus() + { + return $this->status; + } + + /** + * Set status + * + * @param bool $bool + * + * @return $this + */ + public function setStatus($bool) + { + $this->status = $bool; + + return $this; + } + + /** + * Converts this object to an array in the format expected by CloudFlare + * + * @return array + */ + public function toArray() + { + + $output = array( + 'targets' => $this->targets->toArray(), + 'actions' => $this->actions->toArray(), + 'priority' => (int)$this->priority, + 'status' => ($this->status) ? 'active' : 'disabled' + ); + + if (isset($this->identifier)) { + $output = array_merge(array('id' => $this->identifier), $output); + } + + return $output; + } + + /** + * Converts this object to a JSON string in the format expected by CloudFlare + * + * @return array + */ + public function toJson() + { + return json_encode($this->toArray()); + } + + /** + * Gets the dynamic endpoint. Appends the rule identifier if the current object represents a rule + * that already exists in CloudFlare + * + * @return string + */ + public function getEndpoint() + { + $endpoint = rtrim(RuleHandler::singleton()->getEndpoint(), '/'); + if ($this->identifier) { + $endpoint = $endpoint . '/' . $this->identifier; + } + + return $endpoint; + } +} \ No newline at end of file diff --git a/code/Rules/Items/RuleItemList.php b/code/Rules/Items/RuleItemList.php new file mode 100644 index 0000000..87914b8 --- /dev/null +++ b/code/Rules/Items/RuleItemList.php @@ -0,0 +1,52 @@ +items)) { + return; + } + + $this->items[] = $item; + } + + /** + * Converts all children of this object into an array + * + * @return array + */ + public function toArray() + { + $stack = array(); + + foreach ($this->items as $item) { + $stack[] = $item->toArray(); + } + + return $stack; + } + + /** + * Converts all children of this object into an array and outputs it as JSON + * + * @return string + */ + public function toJson() + { + return json_encode($this->toArray()); + } +} \ No newline at end of file diff --git a/code/Rules/Items/Targets/RuleTarget.php b/code/Rules/Items/Targets/RuleTarget.php new file mode 100644 index 0000000..150653b --- /dev/null +++ b/code/Rules/Items/Targets/RuleTarget.php @@ -0,0 +1,125 @@ +value; + } + + /** + * Sets the value for this target; which is what the inheriting page rule will trigger against + * + * @example *.example.com/* + * + * @param string $value Usually a domain mask + * + * @return $this + */ + public function setValue($value) + { + $this->value = $value; + + return $this; + } + + /** + * Gets the matching operator, by default "match" + * @return string + */ + public function getOperator() + { + return $this->operator; + } + + /** + * Sets the matching operator. Default: "match" + * + * @param string $operator + * + * @return $this + */ + public function setOperator($operator) + { + $this->operator = $operator; + + return $this; + } + + /** + * Gets the target of this object. Default: "url" + * + * @return string + */ + public function getTarget() + { + return $this->target; + } + + /** + * Sets the target of this object. Default: "url" + * + * @param string $target + * + * @return $this + */ + public function setTarget($target) + { + $this->target = $target; + + return $this; + } + + /** + * Converts this object to an array in the format expected by CloudFlare + * + * @return array + */ + public function toArray() + { + return array( + "target" => $this->getTarget(), + "constraint" => array( + "operator" => $this->getOperator(), + "value" => $this->getValue() + ) + ); + } + + /** + * Converts this object to a JSON string in the format expected by CloudFlare + * + * @return array + */ + public function toJson() + { + return json_encode($this->toArray()); + } + +} \ No newline at end of file diff --git a/code/Rules/Items/Targets/RuleTargetList.php b/code/Rules/Items/Targets/RuleTargetList.php new file mode 100644 index 0000000..93d2912 --- /dev/null +++ b/code/Rules/Items/Targets/RuleTargetList.php @@ -0,0 +1,52 @@ +items)) { + return; + } + + $this->items[] = $item; + } + + /** + * Converts all children of this object into an array + * + * @return array + */ + public function toArray() + { + $stack = array(); + + foreach ($this->items as $item) { + $stack[] = $item->toArray(); + } + + return $stack; + } + + /** + * Converts all children of this object into an array and outputs it as JSON + * + * @return string + */ + public function toJson() + { + return json_encode($this->toArray()); + } +} \ No newline at end of file diff --git a/code/Rules/RuleHandler.php b/code/Rules/RuleHandler.php new file mode 100644 index 0000000..214216f --- /dev/null +++ b/code/Rules/RuleHandler.php @@ -0,0 +1,104 @@ +load(static::CF_PAGERULES_CACHE_KEY)) { + $json = $cache; + } + + if (!isset($json) || $json) { + $json = CloudFlare::singleton()->curlRequest( + $this->getEndpoint(), + array( + 'status' => 'active', + 'order' => 'priority', + 'direction' => 'desc', + 'match' => 'all' + ), + 'GET' + ); + + Cache::set_cache_lifetime('CloudFlare', 60 * 30); + $cacheFactory->save($json, static::CF_PAGERULES_CACHE_KEY); + } + + $array = json_decode($json, true); + $rules = $array['result']; + + $list = RuleItemList::create(); + foreach ($rules as $rule) { + $list->push(RuleItem::create()->load($rule)); + } + + return $list; + } + + /** + * @return string + */ + public function getEndpoint() + { + $zoneId = CloudFlare::singleton()->fetchZoneID(); + + return str_replace(":identifier", $zoneId, static::$endpoint); + } + + /** + * Invalidates the cache, usually called after making a change to a rule + * + * @return bool + */ + public static function flush() { + return Cache::factory('CloudFlare')->remove(static::CF_PAGERULES_CACHE_KEY); + } +} \ No newline at end of file