From 8b8e0bb29274a9b9782391617ec86ed3704c31a9 Mon Sep 17 00:00:00 2001 From: Laurens Martina Date: Wed, 6 Jan 2021 10:15:43 +0100 Subject: [PATCH 1/3] WIP: adds datatable to index datatype. --- system/core/pages.php | 66 +++++++++++ system/datatypes/index.php | 126 ++++++++++++++++----- system/datatypes/peer_reviewed_article.php | 31 +++++ 3 files changed, 197 insertions(+), 26 deletions(-) diff --git a/system/core/pages.php b/system/core/pages.php index 4b9b3ee6..27b7ca4a 100644 --- a/system/core/pages.php +++ b/system/core/pages.php @@ -47,6 +47,11 @@ abstract class HyphaSystemPage extends HyphaPage { abstract class for a page backed by datatype and xml file. */ abstract class HyphaDatatypePage extends HyphaPage { + const INDEX_TABLE_COLUMNS_TITLE = 'title'; + const INDEX_TABLE_COLUMNS_AUTHOR = 'author'; + const INDEX_TABLE_COLUMNS_DATE = 'date'; + const INDEX_TABLE_COLUMNS_STATUS = 'status'; + public $pageListNode, $language, $pagename, $privateFlag; function __construct(HyphaDomElement $node, RequestContext $O_O) { @@ -54,10 +59,45 @@ function __construct(HyphaDomElement $node, RequestContext $O_O) { $this->replacePageListNode($node); } + /** + * @return string + */ public static function getDatatypeName() { return str_replace('_', ' ', get_called_class()); } + /** + * @return array + */ + public static function getIndexTableColumns() { + return [ + __(self::INDEX_TABLE_COLUMNS_TITLE), + __(self::INDEX_TABLE_COLUMNS_AUTHOR), + __(self::INDEX_TABLE_COLUMNS_DATE), + ]; + } + + /** + * @return array + */ + public function getIndexData() { + $id = $this->pageListNode->getAttribute('id'); + $date = $this->getSortDateTime(); + $dataMtx = [ + __(self::INDEX_TABLE_COLUMNS_TITLE) => [ + 'class' => 'type_'.get_class($this).' '.($this->privateFlag ? 'is-private' : 'is-public'), + 'sort' => preg_replace("/[^A-Za-z0-9]/", '', $this->getTitle()).'_'.$id, + 'value' => ''.$this->getTitle().'', + ], + __(self::INDEX_TABLE_COLUMNS_AUTHOR) => $this->getAuthor(), + __(self::INDEX_TABLE_COLUMNS_DATE) => [ + 'sort' => $date ? $date->format('YmdHis') : '', + 'value' => $date ? $date->format('Y-m-d') : '', + ], + ]; + return array_intersect_key($dataMtx, array_fill_keys(self::getIndexTableColumns(), '')); + } + protected function deletePage() { global $hyphaXml, $hyphaUser; $id = $this->pageListNode->getAttribute('id'); @@ -92,6 +132,32 @@ public function getTitle() { return showPagename($this->pagename); } + /** + * @return null|string + */ + public function getAuthor() { + $v = $this->getLatestVersion(); + return $v ? $v->getAttribute('author') : null; + } + + /** + * @return null|string + */ + public function getLatestVersion() { + if ($this->xml->hasVersions() && $this->xml->getElementById($this->language)) { + $history = []; + foreach($this->xml->getElementById($this->language)->getElementsByTagName('version') as $v) { + $timestamp = $v->getAttribute('xml:id'); + $history[$timestamp] = $v; + } + if (!empty($history)) { + krsort($history); + return reset($history); + } + } + return null; + } + public function renderSingleLine(HyphaDomElement $container) { $h2 = $container->document()->createElement('h2'); $h2->setText($this->getTitle()); diff --git a/system/datatypes/index.php b/system/datatypes/index.php index e5c743a8..7eae1737 100644 --- a/system/datatypes/index.php +++ b/system/datatypes/index.php @@ -39,42 +39,116 @@ public function pageIndexView(HyphaRequest $request) { $languageName = $isoLangList[$language]; $languageName = substr($languageName, 0, strpos($languageName, ' (')); + $this->html->linkScript('//cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js'); + $this->html->linkStyle('//cdn.datatables.net/1.10.22/css/jquery.dataTables.min.css'); + + $html = << + + + [[headerItems]] + + + + [[tbody]] + +
+TABLE; + + $tRowTpl = << + [[recordItems]] + +ROW; + $tRowItemTpl = <<[[value]] +ROWITEM; + + $dataTypes = hypha_getDataTypes(); + // get list of available pages and sort alphabetically $pageList = []; - foreach(hypha_getPageList() as $page) { + foreach(hypha_getPageList() as $index => $page) { $lang = hypha_pageGetLanguage($page, $language); - if ($lang) if ($this->O_O->isUser() || ($page->getAttribute('private')!='on')) { - $pageList[] = $lang->getAttribute('name').($page->getAttribute('private')=='on' ? '&#;' : ''); - $pageListDatatype[$lang->getAttribute('name')] = $page->getAttribute('type'); + $isPrivateOrUser = $this->O_O->isUser() || ($page->getAttribute('private') != 'on'); + $isInDataType = array_key_exists($page->getAttribute('type'), $dataTypes); + if ($lang && $isPrivateOrUser && $isInDataType) { + /** @var HyphaDatatypePage $hyphaPage */ + $hyphaPage = createPageInstance($this->O_O, $page); + $titleSort = preg_replace("/[^A-Za-z0-9]/", '', $hyphaPage->getTitle()); + $titleSort .= '_'.$index; + $pageList[$titleSort] = $hyphaPage; } } - if ($pageList) array_multisort(array_map('strtolower', $pageList), $pageList); - - // add capitals - $capital = 'A'; - $first = true; - $htmlList = []; - if ($pageList) foreach($pageList as $pagename) { - while($capital < strtoupper($pagename[0])) $capital++; - if (strtoupper($pagename[0]) == $capital) { - if (!$first) { - $htmlList[] = ''; + ksort($pageList); + + $columns = []; + foreach ($dataTypes as $class => $name) { + $cols = call_user_func($class . '::getIndexTableColumns'); + $columns += array_combine($cols, $cols); + } + + $tbody = ''; + // iterate over page list + foreach($pageList as $titleSort => $hyphaPage) { + $recordItems = ''; + $items = $hyphaPage->getIndexData(); + foreach ($columns as $name) { + if (array_key_exists($name, $items)) { + $item = $items[$name]; + } else { + $item = ''; + } + if (!is_array($item)) { + $item = ['value' => $item]; + } + + $vars = ['name' => $name]; + foreach (['value', 'sort', 'class'] as $key) { + if (array_key_exists($key, $item)) { + $vars[$key] = $item[$key]; + } } - $htmlList[] = '
'; - $htmlList[] = '
'.$capital.'
'; - $capital++; - $first = false; + $recordItems .= hypha_substitute($tRowItemTpl, $vars); } - $privatePos = strpos($pagename, '&#;'); - if ($privatePos) $pagename = substr($pagename, 0, $privatePos); - $htmlList[] = ''; + + $vars = [ + 'recordItems' => $recordItems, + ]; + + $tbody .= hypha_substitute($tRowTpl, $vars); + } + + $headerItems = ''; + foreach ($columns as $column) { + $headerItems .= ''.$column.''; } - $html = '
'; - foreach($htmlList as $htmlLine) $html.= $htmlLine; - $html.= '
'; + $vars = [ + 'headerItems' => $headerItems, + 'tbody' => $tbody, + ]; + + $html = hypha_substitute($html, $vars); + + // initialize datatable + $js = << $dateIndex, + ]; + $js = hypha_substitute($js, $vars); + $this->html->writeScript($js); $this->html->writeToElement('pagename', __('page-index').': '.$languageName); $this->html->writeToElement('main', $html); + } } -} diff --git a/system/datatypes/peer_reviewed_article.php b/system/datatypes/peer_reviewed_article.php index d381d6db..6df98eda 100644 --- a/system/datatypes/peer_reviewed_article.php +++ b/system/datatypes/peer_reviewed_article.php @@ -2030,6 +2030,30 @@ protected function sendMail($receivers, $subject, $message) { sendMail($receivers, hypha_getTitle() . ': '. $subject, $message, hypha_getEmail(), hypha_getTitle(), $style); } + /** + * @return array + */ + public static function getIndexTableColumns() { + $columns = parent::getIndexTableColumns(); + if (isUser()) { + $columns[] = __(self::INDEX_TABLE_COLUMNS_STATUS); + } + return $columns; + } + + /** + * @return array + */ + public function getIndexData() { + $dataMtx = [ + __(self::INDEX_TABLE_COLUMNS_STATUS) => [ + 'value' => $this->getStatus(), + 'sort' => $this->getStatus(), + ], + ] + parent::getIndexData(); + return array_intersect_key($dataMtx, array_fill_keys(self::getIndexTableColumns(), '')); + } + /** * Gets the article title. * @@ -2047,6 +2071,13 @@ public function getTitle() { return $title; } + /** + * @return string + */ + public function getAuthor() { + return $this->xml->find(self::FIELD_NAME_ARTICLE)->getAttribute(self::FIELD_NAME_AUTHOR); + } + /** * Gets the article excerpt. * From 6b7400163ecc84cfe23c84c6e8c60c0ef7a4b5ec Mon Sep 17 00:00:00 2001 From: Laurens Martina Date: Wed, 6 Jan 2021 11:31:46 +0100 Subject: [PATCH 2/3] Adds filter index data function --- system/core/pages.php | 19 +++++++++++++++++-- system/datatypes/peer_reviewed_article.php | 4 ++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/system/core/pages.php b/system/core/pages.php index 27b7ca4a..6120b87a 100644 --- a/system/core/pages.php +++ b/system/core/pages.php @@ -83,7 +83,7 @@ public static function getIndexTableColumns() { public function getIndexData() { $id = $this->pageListNode->getAttribute('id'); $date = $this->getSortDateTime(); - $dataMtx = [ + $data = [ __(self::INDEX_TABLE_COLUMNS_TITLE) => [ 'class' => 'type_'.get_class($this).' '.($this->privateFlag ? 'is-private' : 'is-public'), 'sort' => preg_replace("/[^A-Za-z0-9]/", '', $this->getTitle()).'_'.$id, @@ -95,7 +95,22 @@ public function getIndexData() { 'value' => $date ? $date->format('Y-m-d') : '', ], ]; - return array_intersect_key($dataMtx, array_fill_keys(self::getIndexTableColumns(), '')); + return $this->filterIndexData($data); + } + + /** + * @param array $data + * + * @return array + */ + protected function filterIndexData(array $data) { + $availableColumns = self::getIndexTableColumns(); + foreach ($data as $column => $dataPerColumn) { + if (!in_array($column, $availableColumns)) { + unset($data[$column]); + } + } + return $data; } protected function deletePage() { diff --git a/system/datatypes/peer_reviewed_article.php b/system/datatypes/peer_reviewed_article.php index 6df98eda..b9b545e9 100644 --- a/system/datatypes/peer_reviewed_article.php +++ b/system/datatypes/peer_reviewed_article.php @@ -2045,13 +2045,13 @@ public static function getIndexTableColumns() { * @return array */ public function getIndexData() { - $dataMtx = [ + $data = [ __(self::INDEX_TABLE_COLUMNS_STATUS) => [ 'value' => $this->getStatus(), 'sort' => $this->getStatus(), ], ] + parent::getIndexData(); - return array_intersect_key($dataMtx, array_fill_keys(self::getIndexTableColumns(), '')); + return $this->filterIndexData($data); } /** From 0593b43c5af43645cb1d696505026a3548fe00d8 Mon Sep 17 00:00:00 2001 From: Laurens Martina Date: Wed, 6 Jan 2021 11:37:16 +0100 Subject: [PATCH 3/3] Updates translation --- system/core/pages.php | 8 ++++---- system/languages/en.php | 8 +++++++- system/languages/nl.php | 6 ++++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/system/core/pages.php b/system/core/pages.php index 6120b87a..8f0988b2 100644 --- a/system/core/pages.php +++ b/system/core/pages.php @@ -47,10 +47,10 @@ abstract class HyphaSystemPage extends HyphaPage { abstract class for a page backed by datatype and xml file. */ abstract class HyphaDatatypePage extends HyphaPage { - const INDEX_TABLE_COLUMNS_TITLE = 'title'; - const INDEX_TABLE_COLUMNS_AUTHOR = 'author'; - const INDEX_TABLE_COLUMNS_DATE = 'date'; - const INDEX_TABLE_COLUMNS_STATUS = 'status'; + const INDEX_TABLE_COLUMNS_TITLE = 'index_table_column_title'; + const INDEX_TABLE_COLUMNS_AUTHOR = 'index_table_column_author'; + const INDEX_TABLE_COLUMNS_DATE = 'index_table_column_date'; + const INDEX_TABLE_COLUMNS_STATUS = 'index_table_column_status'; public $pageListNode, $language, $pagename, $privateFlag; diff --git a/system/languages/en.php b/system/languages/en.php index 331bcfcf..cf293e6f 100644 --- a/system/languages/en.php +++ b/system/languages/en.php @@ -497,7 +497,13 @@ "art-date-format-date" => "%B %e, %Y", // see for format: https://www.php.net/manual/en/function.date.php "art-date-format-time" => "at %l:%M%p", // see for format: https://www.php.net/manual/en/function.date.php "art-read-more" => "Read more", - + + // index + "index_table_column_title" => "title", + "index_table_column_author" => "author", + "index_table_column_date" => "date", + "index_table_column_status" => "status", + // sharing links "share-email-subject" => "See '[[title]]' at [[domain]]", "share-email-body" => "I came across '[[title]]' at [[domain]]: [[url]]", diff --git a/system/languages/nl.php b/system/languages/nl.php index 95ea9c80..672b6cbd 100644 --- a/system/languages/nl.php +++ b/system/languages/nl.php @@ -493,6 +493,12 @@ "art-date-format-time" => "om %k:%Mu", // see for format: https://www.php.net/manual/en/function.date.php "art-read-more" => "Lees meer", + // index + "index_table_column_title" => "title", + "index_table_column_author" => "author", + "index_table_column_date" => "date", + "index_table_column_status" => "status", + // sharing links "share-email-subject" => "Zie '[[title]]' op [[domain]]", "share-email-body" => "Ik kwam '[[title]]' tegen op [[domain]]: [[url]]",