Files
FHC-Core/application/libraries/CmsAdminLib.php
T

558 lines
15 KiB
PHP

<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class CmsAdminLib
{
private $ci;
public function __construct()
{
$this->ci =& get_instance();
$this->ci->load->model('content/Content_model', 'ContentModel');
$this->ci->load->model('content/Contentsprache_model', 'ContentspracheModel');
$this->ci->load->model('content/Contentchild_model', 'ContentchildModel');
$this->ci->load->model('content/Contentgruppe_model', 'ContentgruppeModel');
$this->ci->load->model('content/Contentlog_model', 'ContentlogModel');
$this->ci->load->model('content/Template_model', 'TemplateModel');
$this->ci->load->library('XsdSchemaLib');
$this->ci->load->library('PermissionLib');
$this->ci->config->load('cms');
}
/**
* @return object success(array) entitled oe_kurzbz values
*/
public function getEntitledOe()
{
$oe = $this->ci->permissionlib->getOE_isEntitledFor('basis/cms');
if ($oe === false || !is_array($oe))
return success([]);
return success($oe);
}
// LEGACY-QUIRK: the legacy code checks the organisational unit only when it loads the
// page. It does not check on each write. This method exists, but it is called only
// where the legacy code calls it. See Q7 in the contract.
/**
* @param int $content_id
* @return object success(bool)
*/
public function isEntitledForContent($content_id)
{
$oeResult = $this->ci->ContentModel->getOeKurzbz($content_id);
if (isError($oeResult))
return $oeResult;
$entitledResult = $this->getEntitledOe();
if (isError($entitledResult))
return $entitledResult;
return success(in_array(getData($oeResult), getData($entitledResult)));
}
/**
* @return object success(string) or error
*/
public function getDefaultOe()
{
$default = $this->ci->config->item('default_oe_kurzbz');
$entitledResult = $this->getEntitledOe();
if (isError($entitledResult))
return $entitledResult;
$entitled = getData($entitledResult);
if (empty($entitled))
return error('cms/keineBerechtigteOe');
if (in_array($default, $entitled))
return success($default);
return success($entitled[0]);
}
/**
* @param int|null $parent_content_id
* @return object success(array) with content_id, sprache, version
*/
public function createContent($parent_content_id = null)
{
$templatesResult = $this->ci->TemplateModel->loadWhere([]);
if (isError($templatesResult))
return $templatesResult;
$templates = getData($templatesResult);
if (empty($templates))
return error('cms/keineVorlageVorhanden');
$template = $templates[0];
$oeResult = $this->getDefaultOe();
if (isError($oeResult))
return $oeResult;
$oe = getData($oeResult);
$this->ci->load->library('PhrasesLib');
$phraseResult = $this->ci->phraseslib->getPhrases(
'cms', DEFAULT_LANGUAGE, 'neuerEintrag', null, null, 'no'
);
$titel = $phraseResult->retval[0]->text;
$now = date('Y-m-d H:i:s');
$uid = getAuthUID();
$this->ci->db->trans_start();
$contentResult = $this->ci->ContentModel->insert([
'template_kurzbz' => $template->template_kurzbz,
'oe_kurzbz' => $oe,
'aktiv' => true,
'menu_open' => false,
'beschreibung' => '',
'insertamum' => $now,
'insertvon' => $uid
]);
if (isError($contentResult))
return $contentResult;
$content_id = getData($contentResult);
$spracheResult = $this->ci->ContentspracheModel->insert([
'content_id' => $content_id,
'sprache' => DEFAULT_LANGUAGE,
'version' => 1,
'sichtbar' => true,
'titel' => $titel,
'content' => '<?xml version="1.0" encoding="UTF-8" ?><content></content>',
'insertamum' => $now,
'insertvon' => $uid
]);
if (isError($spracheResult))
return $spracheResult;
if ($parent_content_id !== null)
{
$maxSortResult = $this->ci->ContentchildModel->getMaxSort($parent_content_id);
if (isError($maxSortResult))
return $maxSortResult;
$childResult = $this->ci->ContentchildModel->insert([
'content_id' => $parent_content_id,
'child_content_id' => $content_id,
'sort' => getData($maxSortResult) + 1,
'insertamum' => $now,
'insertvon' => $uid
]);
if (isError($childResult))
return $childResult;
}
$this->ci->db->trans_complete();
if ($this->ci->db->trans_status() === false)
return error('cms/speichernFehlgeschlagen');
return success([
'content_id' => $content_id,
'sprache' => DEFAULT_LANGUAGE,
'version' => 1
]);
}
/**
* @param int $content_id
* @param string $sprache source language
* @param int $version source version
* @param string $neueSprache target language
* @return object success(array) with contentsprache_id
*/
public function createTranslation($content_id, $sprache, $version, $neueSprache)
{
$existsResult = $this->ci->ContentspracheModel->exists($content_id, $neueSprache);
if (isError($existsResult))
return $existsResult;
if (getData($existsResult))
return error('cms/uebersetzungExistiert');
$sourceResult = $this->ci->ContentspracheModel->getOne($content_id, $sprache, $version);
if (isError($sourceResult))
return $sourceResult;
$source = getData($sourceResult);
$now = date('Y-m-d H:i:s');
$uid = getAuthUID();
$insertResult = $this->ci->ContentspracheModel->insert([
'content_id' => $content_id,
'sprache' => $neueSprache,
'version' => $source->version,
'sichtbar' => true,
'titel' => $source->titel,
'content' => $source->content,
// The review feature is gone from this admin, but the columns stay and the
// legacy admin still writes them. A copied row must not inherit the review
// stamp of its source, so we clear it here.
'reviewvon' => null,
'reviewamum' => null,
'gesperrt_uid' => null,
'insertamum' => $now,
'insertvon' => $uid,
'updateamum' => $now,
'updatevon' => $uid
]);
if (isError($insertResult))
return $insertResult;
return success(['contentsprache_id' => getData($insertResult)]);
}
/**
* @param int $content_id
* @param string $sprache
* @return object success(array) with version
*/
public function createVersion($content_id, $sprache)
{
$sourceResult = $this->ci->ContentspracheModel->getOne($content_id, $sprache, null);
if (isError($sourceResult))
return $sourceResult;
$source = getData($sourceResult);
$maxResult = $this->ci->ContentspracheModel->getMaxVersion($content_id, $sprache);
if (isError($maxResult))
return $maxResult;
$newVersion = getData($maxResult) + 1;
$now = date('Y-m-d H:i:s');
$uid = getAuthUID();
$insertResult = $this->ci->ContentspracheModel->insert([
'content_id' => $content_id,
'sprache' => $sprache,
'version' => $newVersion,
'sichtbar' => false,
'titel' => $source->titel,
'content' => $source->content,
// The review feature is gone from this admin, but the columns stay and the
// legacy admin still writes them. A copied row must not inherit the review
// stamp of its source, so we clear it here.
'reviewvon' => null,
'reviewamum' => null,
'gesperrt_uid' => null,
'insertamum' => $now,
'insertvon' => $uid,
'updateamum' => $now,
'updatevon' => $uid
]);
if (isError($insertResult))
return $insertResult;
return success(['version' => $newVersion]);
}
/**
* @param array $daten fields from contract 7.7
* @return object success(true) or error
*/
public function saveProperties($daten)
{
$versionResult = $this->ci->ContentspracheModel->getOne(
$daten['content_id'], $daten['sprache'], $daten['version']
);
if (isError($versionResult))
return $versionResult;
$row = getData($versionResult);
$now = date('Y-m-d H:i:s');
$uid = getAuthUID();
$this->ci->db->trans_start();
$this->ci->ContentModel->update($daten['content_id'], [
'template_kurzbz' => $daten['template_kurzbz'],
'oe_kurzbz' => $daten['oe_kurzbz'],
'aktiv' => $daten['aktiv'],
'menu_open' => $daten['menu_open'],
'beschreibung' => $daten['beschreibung'],
'updateamum' => $now,
'updatevon' => $uid
]);
// LEGACY-QUIRK: prefs_save sets updateamum and updatevon in tbl_content only.
// It does not touch tbl_contentsprache. Kept as a functional copy.
$this->ci->ContentspracheModel->update($row->contentsprache_id, [
'titel' => $daten['titel'],
'sichtbar' => $daten['sichtbar']
]);
$this->ci->db->trans_complete();
if ($this->ci->db->trans_status() === false)
return error('cms/speichernFehlgeschlagen');
return success(true);
}
// LEGACY-QUIRK: the legacy XSDFormPrinter_XML branch checks neither the permission
// type nor the lock. The form appears only when the user holds the lock, but the POST
// itself is unprotected. See Q3 in the contract.
/**
* @param int $content_id
* @param string $sprache
* @param int $version
* @param array $values field name => value
* @return object success(true) or error
*/
public function saveContentXml($content_id, $sprache, $version, $values)
{
$versionResult = $this->ci->ContentspracheModel->getOne($content_id, $sprache, $version);
if (isError($versionResult))
return $versionResult;
$row = getData($versionResult);
$contentResult = $this->ci->ContentModel->load($content_id);
if (isError($contentResult))
return $contentResult;
$content = getData($contentResult);
if (empty($content))
return error('cms/contentNichtGefunden');
$templateResult = $this->ci->TemplateModel->load($content[0]->template_kurzbz);
if (isError($templateResult))
return $templateResult;
$template = getData($templateResult);
if (empty($template))
return error('cms/keineVorlageVorhanden');
$schemaResult = $this->ci->xsdschemalib->parseSchema(
$template[0]->xsd, $content[0]->template_kurzbz
);
if (isError($schemaResult))
return $schemaResult;
$xmlResult = $this->ci->xsdschemalib->buildXml(getData($schemaResult), $values);
if (isError($xmlResult))
return $xmlResult;
$updateResult = $this->ci->ContentspracheModel->update(
$row->contentsprache_id,
['content' => getData($xmlResult)]
);
if (isError($updateResult))
return $updateResult;
return success(true);
}
// LEGACY-QUIRK: content::sperren does not check for an existing lock.
// A second user overwrites the first lock. See Q2 in the contract.
/**
* @param int $contentsprache_id
* @return object success(true) or error
*/
public function lock($contentsprache_id)
{
$uid = getAuthUID();
$this->ci->db->trans_start();
$logResult = $this->ci->ContentlogModel->insert([
'uid' => $uid,
'contentsprache_id' => $contentsprache_id,
'start' => date('Y-m-d H:i:s')
]);
if (isError($logResult))
return $logResult;
$updateResult = $this->ci->ContentspracheModel->update($contentsprache_id, [
'gesperrt_uid' => $uid
]);
if (isError($updateResult))
return $updateResult;
$this->ci->db->trans_complete();
if ($this->ci->db->trans_status() === false)
return error('cms/speichernFehlgeschlagen');
return success(true);
}
// LEGACY-QUIRK: content::freigabeUser releases ALL locks of the user, not only the
// lock on this page. Kept as a functional copy. See Q1 in the contract.
/**
* @return object success(true)
*/
public function releaseOwnLocks()
{
$uid = getAuthUID();
$this->ci->db->trans_start();
$this->ci->db->query(
'UPDATE campus.tbl_contentlog SET ende = now() WHERE uid = ? AND ende IS NULL',
[$uid]
);
$this->ci->db->query(
'UPDATE campus.tbl_contentsprache SET gesperrt_uid = NULL WHERE gesperrt_uid = ?',
[$uid]
);
$this->ci->db->trans_complete();
if ($this->ci->db->trans_status() === false)
return error('cms/speichernFehlgeschlagen');
return success(true);
}
/**
* @param int $contentsprache_id
* @return object success(true)
*/
public function forceRelease($contentsprache_id)
{
$this->ci->db->trans_start();
$this->ci->db->query(
'UPDATE campus.tbl_contentlog SET ende = now() WHERE contentsprache_id = ? AND ende IS NULL',
[$contentsprache_id]
);
$this->ci->db->query(
'UPDATE campus.tbl_contentsprache SET gesperrt_uid = NULL WHERE contentsprache_id = ?',
[$contentsprache_id]
);
$this->ci->db->trans_complete();
if ($this->ci->db->trans_status() === false)
return error('cms/speichernFehlgeschlagen');
return success(true);
}
/**
* @param int $content_id
* @param string $sprache
* @param int $version
* @return object success(array) lock state per contract 7.8
*/
public function getLockState($content_id, $sprache, $version)
{
$versionResult = $this->ci->ContentspracheModel->getOne($content_id, $sprache, $version);
if (isError($versionResult))
return $versionResult;
$row = getData($versionResult);
$lockResult = $this->ci->ContentlogModel->getOpenLock($row->contentsprache_id);
$logEntry = (!isError($lockResult)) ? getData($lockResult) : null;
// LEGACY-QUIRK: admin.php inserts an empty string, releasing writes NULL. Both mean
// free. The contract reports NULL.
$gesperrt_uid = ($row->gesperrt_uid === '') ? null : $row->gesperrt_uid;
return success([
'contentsprache_id' => (int) $row->contentsprache_id,
'gesperrt_uid' => $gesperrt_uid,
'start' => $logEntry ? $logEntry->start : null,
'own' => ($gesperrt_uid !== null && $gesperrt_uid === getAuthUID()),
'may_force' => $this->ci->permissionlib->isBerechtigt('basis/cms_sperrfreigabe', 'su')
]);
}
// DEVIATION: admin.php ignores the return value of deleteContent and tells the user
// nothing. This code reports the error. See Q5 in the contract.
/**
* @param int $content_id
* @return object success(true) or error
*/
public function deleteContent($content_id)
{
$this->ci->db->trans_start();
$this->ci->db->query(
'DELETE FROM campus.tbl_contentchild WHERE content_id = ?',
[$content_id]
);
$this->ci->db->query(
'DELETE FROM campus.tbl_contentchild WHERE child_content_id = ?',
[$content_id]
);
$this->ci->db->query(
'DELETE FROM campus.tbl_contentlog WHERE contentsprache_id IN (SELECT contentsprache_id FROM campus.tbl_contentsprache WHERE content_id = ?)',
[$content_id]
);
$this->ci->db->query(
'DELETE FROM campus.tbl_contentsprache WHERE content_id = ?',
[$content_id]
);
$this->ci->db->query(
'DELETE FROM campus.tbl_contentgruppe WHERE content_id = ?',
[$content_id]
);
$this->ci->db->query(
'DELETE FROM campus.tbl_content WHERE content_id = ?',
[$content_id]
);
$this->ci->db->trans_complete();
if ($this->ci->db->trans_status() === false)
return error('cms/loeschenNichtMoeglichReferenzen');
return success(true);
}
/**
* @param int $content_id
* @param string $sprache
* @param int $version
* @return object success(true) or error
*/
public function deleteVersion($content_id, $sprache, $version)
{
if ($sprache === DEFAULT_LANGUAGE)
{
$countResult = $this->ci->ContentspracheModel->getNumberOfVersions($content_id, $sprache);
if (isError($countResult))
return $countResult;
if (getData($countResult) === 1)
return error('cms/letzteVersionNichtLoeschbar');
}
$versionResult = $this->ci->ContentspracheModel->getOne($content_id, $sprache, $version);
if (isError($versionResult))
return $versionResult;
$row = getData($versionResult);
$this->ci->db->trans_start();
$this->ci->db->query(
'DELETE FROM campus.tbl_contentlog WHERE contentsprache_id = ?',
[$row->contentsprache_id]
);
$this->ci->db->query(
'DELETE FROM campus.tbl_contentsprache WHERE content_id = ? AND sprache = ? AND version = ?',
[$content_id, $sprache, $version]
);
$this->ci->db->trans_complete();
if ($this->ci->db->trans_status() === false)
return error('cms/loeschenFehlgeschlagen');
return success(true);
}
}