Skip to content

Instantly share code, notes, and snippets.

@Pathologic
Last active February 10, 2023 10:02
Show Gist options
  • Save Pathologic/e7a1e3d1d0ce16abb1905d827bbcff79 to your computer and use it in GitHub Desktop.
Save Pathologic/e7a1e3d1d0ce16abb1905d827bbcff79 to your computer and use it in GitHub Desktop.
<?php
class FastResource
{
protected $fields = array();
protected $tvs = array();
protected $tvIds = array();
protected $tvtpl = array();
protected $tvDefaults = array();
protected $modx = null;
public $newDoc = true;
protected $id = false;
public function __construct (DocumentParser $modx)
{
$this->modx = $modx;
$this->loadTVs();
$this->loadTVTpls();
}
public function query($sql = '') {
return $this->modx->db->query($sql);
}
public function escape($value) {
return $this->modx->db->escape($value);
}
public function set($key, $value) {
if (!empty($key)) {
$this->fields[$key] = $value;
}
return $this;
}
public function get($key, $default = '') {
$out = $default;
if (isset($this->fields[$key])) {
$out = $this->fields[$key];
}
return $out;
}
public function close() {
$this->newDoc = true;
$this->fields = array();
$this->id = false;
return $this;
}
public function erase($key) {
unset($this->fields[$key]);
return $this;
}
public function fromArray($fields = array()) {
$this->fields = array_merge($this->fields, $fields);
return $this;
}
public function toArray() {
return $this->fields;
}
public function create($fields = array()) {
$this->close();
$this->fields = $fields;
return $this;
}
public function update($id) {
$this->close();
$id = (int)$id;
if ($id) {
$this->newDoc = false;
$this->id = $id;
}
return $this;
}
protected function loadTVs() {
$q = $this->query("SELECT `id`, `name`, `default_text` FROM {$this->modx->getFullTableName('site_tmplvars')}");
while ($row = $this->modx->db->getRow($q)) {
$this->tvs[$row['name']] = $row['id'];
if (!empty($row['default_text'])) {
$this->tvDefaults[$row['id']] = $row['default_text'];
}
}
$this->tvIds = array_flip($this->tvs);
return $this;
}
protected function loadTVTpls() {
$q = $this->query("SELECT `tmplvarid`, `templateid` FROM {$this->modx->getFullTableName('site_tmplvar_templates')}");
while ($row = $this->modx->db->getRow($q)) {
$this->tvtpl[$row['templateid']][] = $row['tmplvarid'];
}
return $this;
}
public function getID() {
return $this->id;
}
public function edit($id) {
$this->close();
$id = (int)$id;
$q = $this->query("SELECT * FROM {$this->modx->getFullTableName('site_content')} WHERE `id`={$id}");
$row = $this->modx->db->getRow($q);
if ($row) {
$this->fromArray($row);
$this->newDoc = false;
$this->id = $id;
$this->addTVs($id);
}
return $this;
}
public function addTVs($id) {
$id = (int)$id;
$q = $this->query("SELECT `tmplvarid`, `value` FROM {$this->modx->getFullTableName('site_content')} WHERE `contentid`={$id}");
while ($row = $this->modx->db->getRow($q)) {
$tvname = $this->tvIds[$row['tmplvarid']];
$this->set($tvname, $row['value']);
}
}
public function save($invokeEvents = false, $clearCache = false) {
$out = false;
if ($this->newDoc) {
$this->set('createdon', time() + $this->modx->getConfig('server_offset_time'));
$this->set('publishedon', time() + $this->modx->getConfig('server_offset_time'));
$alias = $this->get('alias');
if (empty($alias)) {
$alias = $this->get('pagetitle');
}
$alias = $this->modx->stripAlias($alias);
$this->set('alias', $alias);
} else {
$this->set('editedon', time() + $this->modx->getConfig('server_offset_time'));
}
$fld = $this->toArray();
if (
($this->newDoc &&
(empty($fld['template']) ||
empty($fld['pagetitle']) ||
empty($fld['alias'])))
||
(!$this->newDoc && (
(isset($fld['template']) && empty($fld['template'])) ||
(isset($fld['pagetitle']) && empty($fld['pagetitle'])) ||
(isset($fld['alias']) && empty($fld['alias']))
))
) {
return $out;
}
$insertTVs = $deleteTVs = array();
$template = $fld['template'];
foreach ($fld as $key => $value) {
if(isset($this->tvs[$key])) {
$tvid = $this->tvs[$key];
if (!empty($this->tvtpl[$template]) && in_array($tvid, $this->tvtpl[$template])) {
if ($value === '' || (isset($this->tvDefaults[$tvid]) && $value == $this->tvDefaults[$tvid])) {
$deleteTVs[] = $tvid;
} else {
$insertTVs[$tvid] = $value;
}
}
unset($fld[$key]);
}
}
if (!empty($fld)) {
unset($fld['id']);
if ($this->newDoc) {
$fields = array_keys($fld);
$fields = '`' . implode('`,`', $fields) . '`';
$values = array_values($fld);
foreach ($values as &$value) {
$value = $this->escape($value);
}
unset($value);
$values = "'" . implode("','", $values) . "'";
$sql = "INSERT INTO {$this->modx->getFullTableName('site_content')} ({$fields}) VALUES ({$values})";
$q = $this->query($sql);
if ($id = $this->modx->db->getInsertId($q)) {
$this->id = $id;
$this->set('id', $this->id);
if (!empty($insertTVs)) {
$sql = '';
foreach ($insertTVs as $key => $value) {
$value = "'" . $this->escape($value). "'";
$sql .= '(' . $key . ',' . $id . ',' . $value . '),';
}
$sql = trim($sql, ',');
if ($sql) {
$sql = "INSERT IGNORE INTO {$this->modx->getFullTableName('site_tmplvar_contentvalues')} (`tmplvarid`, `contentid`, `value`) VALUES {$sql}";
$this->query($sql);
}
}
$out = $id;
if ($invokeEvents) {
$this->modx->invokeEvent('OnDocFormSave', array('mode' => 'new', 'id' => $id));
}
}
} else {
$fields = '';
foreach ($fld as $key => $value) {
$value = $this->escape($value);
$fields .= "`{$key}`='{$value}',";
}
$fields = trim($fields, ',');
$sql = "UPDATE {$this->modx->getFullTableName('site_content')} SET {$fields} WHERE `id`={$this->id}";
$q = $this->query($sql);
if ($this->modx->db->getAffectedRows($q)) {
$out = $this->id;
if (!empty($deleteTVs)) {
$ids = implode(',', $deleteTVs);
$q = $this->query("DELETE FROM {$this->modx->getFullTableName('site_tmplvar_contentvalues')} WHERE `contentid`={$this->id} AND `tmplvarid` IN ({$ids})");
}
if (!empty($insertTVs)) {
$fields = '';
foreach ($insertTVs as $key => $value) {
$value = "'" . $this->escape($value). "'";
$fields .= "({$key}, {$this->id}, {$value}),";
}
$fields = trim($fields, ',');
$this->query("INSERT INTO {$this->modx->getFullTableName('site_tmplvar_contentvalues')} (`tmplvarid`, `contentid`, `value`) VALUES {$fields} ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)");
}
if ($invokeEvents) {
$this->modx->invokeEvent('OnDocFormSave', array('mode' => 'upd', 'id' => $this->id));
}
}
}
}
return $out;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment