mirror of
https://github.com/cosmocode/dokuwiki-plugin-struct.git
synced 2025-08-03 15:59:53 +00:00
171 lines
5.5 KiB
PHP
171 lines
5.5 KiB
PHP
<?php
|
|
|
|
namespace dokuwiki\plugin\struct\types;
|
|
|
|
use dokuwiki\plugin\struct\meta\DateFormatConverter;
|
|
use dokuwiki\plugin\struct\meta\QueryBuilder;
|
|
use dokuwiki\plugin\struct\meta\QueryBuilderWhere;
|
|
use dokuwiki\plugin\struct\meta\ValidationException;
|
|
|
|
class DateTime extends Date
|
|
{
|
|
protected $config = [
|
|
'format' => '', // filled by constructor
|
|
'prefilltoday' => false,
|
|
'pastonly' => false,
|
|
'futureonly' => false,
|
|
];
|
|
|
|
/**
|
|
* DateTime constructor.
|
|
*
|
|
* @param array|null $config
|
|
* @param string $label
|
|
* @param bool $ismulti
|
|
* @param int $tid
|
|
*/
|
|
public function __construct($config = null, $label = '', $ismulti = false, $tid = 0)
|
|
{
|
|
global $conf;
|
|
$this->config['format'] = DateFormatConverter::toDate($conf['dformat']);
|
|
|
|
parent::__construct($config, $label, $ismulti, $tid);
|
|
}
|
|
|
|
/**
|
|
* Return the editor to edit a single value
|
|
*
|
|
* @param string $name the form name where this has to be stored
|
|
* @param string $rawvalue the current value
|
|
* @param string $htmlID
|
|
*
|
|
* @return string html
|
|
*/
|
|
public function valueEditor($name, $rawvalue, $htmlID)
|
|
{
|
|
if ($this->config['prefilltoday'] && !$rawvalue) {
|
|
$rawvalue = date('Y-m-d\TH:i');
|
|
}
|
|
$rawvalue = str_replace(' ', 'T', $rawvalue);
|
|
$params = [
|
|
'name' => $name,
|
|
'value' => $rawvalue,
|
|
'class' => 'struct_datetime',
|
|
'type' => 'datetime-local', // HTML5 datetime picker
|
|
'id' => $htmlID,
|
|
];
|
|
$attributes = buildAttributes($params, true);
|
|
return "<input $attributes />";
|
|
}
|
|
|
|
/**
|
|
* Validate a single value
|
|
*
|
|
* This function needs to throw a validation exception when validation fails.
|
|
* The exception message will be prefixed by the appropriate field on output
|
|
*
|
|
* @param string|array $rawvalue
|
|
* @return string
|
|
* @throws ValidationException
|
|
*/
|
|
public function validate($rawvalue)
|
|
{
|
|
$rawvalue = trim($rawvalue);
|
|
[$date, $time] = array_pad(preg_split('/[ |T]/', $rawvalue, 2), 2, '');
|
|
$date = trim($date);
|
|
$time = trim($time);
|
|
|
|
[$year, $month, $day] = explode('-', $date, 3);
|
|
if (!checkdate((int)$month, (int)$day, (int)$year)) {
|
|
throw new ValidationException('invalid datetime format');
|
|
}
|
|
if ($this->config['pastonly'] && strtotime($rawvalue) > time()) {
|
|
throw new ValidationException('pastonly');
|
|
}
|
|
if ($this->config['futureonly'] && strtotime($rawvalue) < time()) {
|
|
throw new ValidationException('futureonly');
|
|
}
|
|
|
|
[$h, $m] = array_pad(explode(':', $time, 3), 2, ''); // drop seconds
|
|
$h = (int)$h;
|
|
$m = (int)$m;
|
|
if ($h < 0 || $h > 23 || $m < 0 || $m > 59) {
|
|
throw new ValidationException('invalid datetime format');
|
|
}
|
|
|
|
return sprintf("%d-%02d-%02d %02d:%02d", $year, $month, $day, $h, $m);
|
|
}
|
|
|
|
/**
|
|
* @param QueryBuilder $QB
|
|
* @param string $tablealias
|
|
* @param string $colname
|
|
* @param string $alias
|
|
*/
|
|
public function select(QueryBuilder $QB, $tablealias, $colname, $alias)
|
|
{
|
|
$col = "$tablealias.$colname";
|
|
|
|
// when accessing the revision column we need to convert from Unix timestamp
|
|
if (is_a($this->context, 'dokuwiki\plugin\struct\meta\RevisionColumn')) {
|
|
$rightalias = $QB->generateTableAlias();
|
|
$QB->addLeftJoin($tablealias, 'titles', $rightalias, "$tablealias.pid = $rightalias.pid");
|
|
$col = "DATETIME($rightalias.lastrev, 'unixepoch', 'localtime')";
|
|
}
|
|
|
|
$QB->addSelectStatement($col, $alias);
|
|
}
|
|
|
|
/**
|
|
* @param QueryBuilderWhere $add
|
|
* @param string $tablealias
|
|
* @param string $colname
|
|
* @param string $comp
|
|
* @param string|\string[] $value
|
|
* @param string $op
|
|
*/
|
|
public function filter(QueryBuilderWhere $add, $tablealias, $colname, $comp, $value, $op)
|
|
{
|
|
$col = "$tablealias.$colname";
|
|
$QB = $add->getQB();
|
|
|
|
// when accessing the revision column we need to convert from Unix timestamp
|
|
if (is_a($this->context, 'dokuwiki\plugin\struct\meta\RevisionColumn')) {
|
|
$rightalias = $QB->generateTableAlias();
|
|
$col = "DATETIME($rightalias.lastrev, 'unixepoch', 'localtime')";
|
|
$QB->addLeftJoin($tablealias, 'titles', $rightalias, "$tablealias.pid = $rightalias.pid");
|
|
}
|
|
|
|
/** @var QueryBuilderWhere $add Where additional queries are added to */
|
|
if (is_array($value)) {
|
|
$add = $add->where($op); // sub where group
|
|
$op = 'OR';
|
|
}
|
|
foreach ((array)$value as $item) {
|
|
$pl = $QB->addValue($item);
|
|
$add->where($op, "$col $comp $pl");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* When sorting `%lastupdated%`, then sort the data from the `titles` table instead the `data_` table.
|
|
*
|
|
* @param QueryBuilder $QB
|
|
* @param string $tablealias
|
|
* @param string $colname
|
|
* @param string $order
|
|
*/
|
|
public function sort(QueryBuilder $QB, $tablealias, $colname, $order)
|
|
{
|
|
$col = "$tablealias.$colname";
|
|
|
|
if (is_a($this->context, 'dokuwiki\plugin\struct\meta\RevisionColumn')) {
|
|
$rightalias = $QB->generateTableAlias();
|
|
$QB->addLeftJoin($tablealias, 'titles', $rightalias, "$tablealias.pid = $rightalias.pid");
|
|
$col = "$rightalias.lastrev";
|
|
}
|
|
|
|
$QB->addOrderBy("$col $order");
|
|
}
|
|
}
|