new StringType('key', -1, true, NULL) )); } public function execute($values = array()) { if(!parent::execute($values)) { return false; } $key = $this->getParam("key"); $sql = $this->user->getSQL(); $query = $sql->select("name", "value") ->from("Settings"); if (!is_null($key) && !empty($key)) { $query->where(new CondRegex(new Column("name"), $key)); } // filter sensitive values, if called from outside if ($this->isExternalCall()) { $query->where(new CondNot("private")); } $res = $query->execute(); $this->success = ($res !== FALSE); $this->lastError = $sql->getLastError(); if ($this->success) { $settings = array(); foreach($res as $row) { $settings[$row["name"]] = $row["value"]; } $this->result["settings"] = $settings; } return $this->success; } } class Set extends SettingsAPI { public function __construct(User $user, bool $externalCall = false) { parent::__construct($user, $externalCall, array( 'settings' => new Parameter('settings', Parameter::TYPE_ARRAY) )); } public function execute($values = array()) { if (!parent::execute($values)) { return false; } $values = $this->getParam("settings"); if (empty($values)) { return $this->createError("No values given."); } $paramKey = new StringType('key', 32); $paramValue = new StringType('value', 1024, true, NULL); $sql = $this->user->getSQL(); $query = $sql->insert("Settings", array("name", "value")); $keys = array(); $deleteKeys = array(); foreach($values as $key => $value) { if (!$paramKey->parseParam($key)) { $key = print_r($key, true); return $this->createError("Invalid Type for key in parameter settings: '$key' (Required: " . $paramKey->getTypeName() . ")"); } else if(!is_null($value) && !$paramValue->parseParam($value)) { $value = print_r($value, true); return $this->createError("Invalid Type for value in parameter settings: '$value' (Required: " . $paramValue->getTypeName() . ")"); } else if(preg_match("/^[a-zA-Z_][a-zA-Z_0-9-]*$/", $paramKey->value) !== 1) { return $this->createError("The property key should only contain alphanumeric characters, underscores and dashes"); } else { if (!is_null($paramValue->value)) { $query->addRow($paramKey->value, $paramValue->value); } else { $deleteKeys[] = $paramKey->value; } $keys[] = $paramKey->value; } } if ($this->isExternalCall()) { $column = $this->checkReadonly($keys); if(!$this->success) { return false; } else if($column !== null) { return $this->createError("Column '$column' is readonly."); } } if (!empty($deleteKeys) && !$this->deleteKeys($keys)) { return false; } if (count($deleteKeys) !== count($keys)) { $query->onDuplicateKeyStrategy(new UpdateStrategy( array("name"), array("value" => new Column("value"))) ); $this->success = ($query->execute() !== FALSE); $this->lastError = $sql->getLastError(); } return $this->success; } private function checkReadonly(array $keys) { $sql = $this->user->getSQL(); $res = $sql->select("name") ->from("Settings") ->where(new CondBool("readonly")) ->where(new CondIn("name", $keys)) ->limit(1) ->execute(); $this->success = ($res !== FALSE); $this->lastError = $sql->getLastError(); if ($this->success && !empty($res)) { return $res[0]["name"]; } return null; } private function deleteKeys(array $keys) { $sql = $this->user->getSQL(); $res = $sql->delete("Settings") ->where(new CondIn("name", $keys)) ->execute(); $this->success = ($res !== FALSE); $this->lastError = $sql->getLastError(); return $this->success; } } }