1<?php 2 3use splitbrain\phpcli\Options; 4use dokuwiki\plugin\structtasks\meta\Utilities; 5use dokuwiki\plugin\structtasks\meta\ReminderNotifier; 6use dokuwiki\plugin\structtasks\meta\TodayNotifier; 7use dokuwiki\plugin\structtasks\meta\OverdueNotifier; 8 9/** 10 * DokuWiki Plugin structtasks (CLI Component) 11 * 12 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 13 * @author Chris MacMackin <cmacmackin@gmail.com> 14 */ 15class cli_plugin_structtasks extends \dokuwiki\Extension\CLIPlugin 16{ 17 18 private $schema; 19 private $struct; 20 private $util; 21 private $dateformat; 22 public $testing = false; 23 public $notifiers = []; 24 25 /** @inheritDoc */ 26 protected function setup(Options $options) 27 { 28 $options->setHelp('Send emails to users that have been assigned to tasks.'); 29 $options->registerOption('verbose', 'Show progress information', 'v', false); 30 } 31 32 /** @inheritDoc */ 33 public function main(Options $options) 34 { 35 $this->notify($options->getOpt('verbose')); 36 } 37 38 /** 39 * Function to run CLI algorithm. 40 */ 41 public function notify($verbose = true) { 42 if (!$this->initialise($verbose)) { 43 exit(-1); 44 } 45 46 $notifiers = $this->createNotifiers( 47 array_map('intval', explode(',', $this->getConf('reminder'))), 48 (bool)$this->getConf('overdue_reminder'), 49 $verbose 50 ); 51 52 $tasks = $this->struct->getPages($this->schema); 53 foreach (array_keys($tasks) as $task) { 54 if ($verbose) $this->notice(sprintf($this->getLang('msg_processing'), $task)); 55 $this->processTask($task, $notifiers); 56 } 57 } 58 59 /** 60 * Sets up useful properties for the class. Returns true if 61 * initialises successfully (e.g., all configurations are valid, 62 * necessary plugins available, etc.), false otherwise. 63 */ 64 public function initialise($verbose = false) : bool { 65 if (!auth_setup()) { 66 if ($verbose) $this->error($this->getLang('msg_no_auth')); 67 return false; 68 } 69 $this->schema = $this->getConf('schema'); 70 if ($this->schema == '') return false; 71 $this->struct = $this->loadHelper('struct', true); 72 if (is_null($this->struct)) return false; 73 $this->util = new Utilities($this->struct); 74 if (!$this->util->isValidSchema($this->schema)) { 75 if ($verbose) $this->error( 76 sprintf($this->getLang('msg_invalid_schema'), $this->schema)); 77 return false; 78 } 79 if ($verbose) $this->success( 80 sprintf($this->getLang('msg_handling_schema'), $this->schema)); 81 $this->dateformat = $this->util->dateFormat($this->schema); 82 return true; 83 } 84 85 /** 86 * Create an array of notifiers based on structtask configurations. 87 * 88 * @param array<int> $reminder_days On which days before the due-date 89 * to send reminders 90 * @param bool $overdue Whether to send reminders for 91 * overdue tasks 92 * @param bool $verbose Whether to print status messages 93 * @return array<AbstractNotifier> 94 */ 95 function createNotifiers($reminder_days, $overdue, $verbose = false) : array { 96 if ($this->testing) return $this->notifiers; 97 $notifiers = []; 98 $getConf = [$this, 'getConf']; 99 $getLang = [$this, 'getLang']; 100 if (($key = array_search(0, $reminder_days)) !== false) { 101 unset($reminder_days[$key]); 102 $notifiers[] = new TodayNotifier($getConf, $getLang); 103 if ($verbose) $this->notice($this->getLang('msg_today_notifier')); 104 } 105 if (count($reminder_days) != 0) { 106 $notifiers[] = new ReminderNotifier($getConf, $getLang, $reminder_days); 107 if ($verbose) { 108 $days = ''; 109 $c = count($reminder_days); 110 if ($c > 1) $days .= implode( 111 ', ', array_slice($reminder_days, 0, -1)) . ' or '; 112 $days .= $reminder_days[$c - 1]; 113 $this->notice( 114 sprintf($this->getLang('msg_reminder_notifier'), $days) 115 ); 116 } 117 } 118 if ($overdue) { 119 $notifiers[] = new OverdueNotifier($getConf, $getLang); 120 if ($verbose) $this->notice($this->getLang('msg_overdue_notifier')); 121 } 122 return $notifiers; 123 } 124 125 /** 126 * Apply notifiers to the specified task 127 * 128 * @param string $task ID for the task page being processed 129 * @param array<AbstractNotifier> $notifiers Notifiers to use with this task 130 */ 131 function processTask($task, $notifiers) : void { 132 $filename = wikiFN($task); 133 $rev = @filemtime($filename); 134 $content = rawWiki($task); 135 $structdata = $this->struct->getData($task, $this->schema)[$this->schema]; 136 $data = $this->util->formatData($structdata, $this->dateformat); 137 $data['content'] = $content; 138 $title = p_get_first_heading($task, METADATA_RENDER_USING_SIMPLE_CACHE); 139 // Doesn't seem to be a simple way to get editor info for 140 // arbitrary pages, so will just leave that blank. It 141 // doesn't actually get used in any of the reminder emails 142 // anyway. 143 $editor_name = ''; 144 $editor_email = ''; 145 foreach ($notifiers as $n) { 146 $n->sendMessage($task, $title, $editor_name, $editor_email, $data, $data); 147 } 148 } 149} 150 151