/** * @param DataObject $obj * @param Array|null $error * @return bool */ public static function update(DataObject &$obj, &$error = null) { if (empty($obj->Id)) { trigger_error('New Data Object cannot be updated'); exit; } if ($obj->getChangedFields()) { $values = $obj->getChangedFields(); $sql = 'UPDATE ' . get_class($obj) . ' SET ' . self::pdoSet($values) . ' WHERE id = :id'; try { $stm = self::$pdo->prepare($sql); $values['id'] = $obj->getId(); if (!$stm->execute($values)) { $error['code'] = $stm->errorCode(); $error['message'] = $stm->errorInfo(); return false; } return true; } catch (\PDOException $ex) { throw $ex; } } return true; }
/** * Is the member the owner of this object, and is the permission being checked * in the list of permissions that owners have? * * @param string $perm * @param Member $member * @return boolean */ protected function checkOwnerPerms(DataObject $node, $perm, $member) { $ownerId = $node->OwnerID; if (!$node) { return; } if ($node->isChanged('OwnerID')) { $changed = $node->getChangedFields(); $ownerId = isset($changed['OwnerID']['before']) && $changed['OwnerID']['before'] ? $changed['OwnerID']['before'] : $ownerId; } if (!$member || $ownerId != $member->ID) { return false; } $cache = $this->getCache(); $perms = $cache->load('ownerperms'); if (!$perms) { // find the owner role and take the permissions of it $ownerRole = DataObject::get_one('AccessRole', '"Title" = \'Owner\''); if ($ownerRole && $ownerRole->exists()) { $perms = $ownerRole->Composes->getValues(); if (is_array($perms)) { $cache->save($perms, 'ownerperms'); } } else { // just fall back to checking OwnerID == $member->ID return $ownerId == $member->ID; } } if (is_array($perms) && in_array($perm, $perms)) { return true; } }
/** * Track a change to a DataObject * @return DataChangeRecord **/ public function track(DataObject $changedObject, $type = 'Change') { $changes = $changedObject->getChangedFields(true, 2); if (count($changes)) { // remove any changes to ignored fields $ignored = $changedObject->getIgnoredFields(); if ($ignored) { $changes = array_diff_key($changes, $ignored); foreach ($ignored as $ignore) { if (isset($changes[$ignore])) { unset($changes[$ignore]); } } } } foreach (self::config()->field_blacklist as $key) { if (isset($changes[$key])) { unset($changes[$key]); } } if (empty($changes) && $type == 'Change' || $type === 'Delete' && Versioned::get_reading_mode() === 'Stage.Live') { return; } $this->ChangeType = $type; $this->ClassType = $changedObject->ClassName; $this->ClassID = $changedObject->ID; // @TODO this will cause issue for objects without titles $this->ObjectTitle = $changedObject->Title; $this->Stage = Versioned::get_reading_mode(); $before = array(); $after = array(); if ($type != 'Change' && $type != 'New') { // If we are (un)publishing we want to store the entire object $before = $type === 'Unpublish' ? $changedObject->toMap() : null; $after = $type === 'Publish' ? $changedObject->toMap() : null; } else { // Else we're tracking the changes to the object foreach ($changes as $field => $change) { if ($field == 'SecurityID') { continue; } $before[$field] = $change['before']; $after[$field] = $change['after']; } } if ($this->Before && $this->Before !== 'null' && is_array($before)) { //merge the old array last to keep it's value as we want keep the earliest version of each field $this->Before = json_encode(array_replace(json_decode($this->Before, true), $before)); } else { $this->Before = json_encode($before); } if ($this->After && $this->After !== 'null' && is_array($after)) { //merge the new array last to keep it's value as we want the newest version of each field $this->After = json_encode(array_replace($after, json_decode($this->After, true))); } else { $this->After = json_encode($after); } if (self::config()->save_request_vars) { foreach (self::config()->request_vars_blacklist as $key) { unset($_GET[$key]); unset($_POST[$key]); } $this->GetVars = isset($_GET) ? json_encode($_GET) : null; $this->PostVars = isset($_POST) ? json_encode($_POST) : null; } $this->ChangedByID = Member::currentUserID(); if (Member::currentUserID() && Member::currentUser()) { $this->CurrentEmail = Member::currentUser()->Email; } if (isset($_SERVER['SERVER_NAME'])) { $protocol = 'http'; $protocol = isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on" ? 'https://' : 'http://'; $this->CurrentURL = $protocol . $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"]; } else { if (Director::is_cli()) { $this->CurrentURL = 'CLI'; } else { $this->CurrentURL = 'Could not determine current URL'; } } $this->RemoteIP = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : (Director::is_cli() ? 'CLI' : 'Unknown remote addr'); $this->Referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''; $this->Agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''; $this->write(); return $this; }