1<?php
2if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../../');
3if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
4
5/**
6 * The Cron Class is just an initial wrapper which tries to create a blank cron.conf.php file
7 * It can also add/edit/delete Cron Jobs that are being configured at the GUI
8 *
9 * @author     i-net software <tools@inetsoftware.de>
10 * @author     Gerry Weissbach <gweissbach@inetsoftware.de>
11 *
12 */
13class cron_plugin_siteexport {
14
15    private $configFile;
16    public $configuration;
17
18    /**
19     * Initial setup for this class
20     */
21    function __construct()
22    {
23        $this->configFile = DOKU_INC . 'conf/cron.config.php';
24        $this->readCronSettings();
25    }
26
27    /**
28     * Save a new entry, or overwrite an existing entry in the cron config
29     * @param $parameters parameters which define the cron job
30     * @param $canOverwrite information if an existing entry should be overwritten
31     */
32    public function saveCronDataWithParameters($parameters, $canOverwrite=false)
33    {
34        if ( !$canOverwrite && $this->hasCronJobForParameters($parameters) )
35        {
36            return "Cannot save. The Cron Job already exists - but no permission given to overwrite";
37        }
38
39        $this->configuration[$this->cronJobNameForParameters($parameters)] = $parameters;
40        if ( !$this->writeCronSettings() ) {
41            return "There was an error while saving the Cron configuration during a save action";
42        }
43    }
44
45    public function deleteCronDataWithParameters($parameters)
46    {
47        unset($this->configuration[$this->cronJobNameForParameters($parameters)]);
48        if ( !$this->writeCronSettings() ) {
49            return "There was an error while saving the Cron configuration during a deletion action";
50        }
51    }
52
53    /**
54     * Reads the Configuration if not loaded yet
55     */
56    public function readCronSettings()
57    {
58        if ( !$this->configFile )
59        {
60            return false;
61        }
62
63        $settings = array();
64        if ( file_exists($this->configFile) )
65        {
66            include($this->configFile);
67        }
68
69        $this->configuration = $settings;
70        return true;
71    }
72
73    /**
74     * Writes the Configuration if it is being set
75     */
76    public function writeCronSettings()
77    {
78        global $conf;
79
80        if ( !$this->configFile )
81        {
82            // Nothing has changed.
83            return true;
84        }
85
86        // backup current file (remove any existing backup)
87        if (@file_exists($this->configFile)) {
88            if (@file_exists($this->configFile.'.bak')) @unlink($this->configFile.'.bak');
89            if (!io_rename($this->configFile, $this->configFile.'.bak')) return false;
90        }
91
92        if (!$fh = @fopen($this->configFile, 'wb')) {
93            io_rename($this->configFile.'.bak', $this->configFile);     // problem opening, restore the backup
94            return false;
95        }
96
97        $out = $this->cronHeading();
98        $out .= $this->recurseSettingsToOut($this->configuration);
99        $out .= $this->cronFooter();
100
101        // Finally write it out.
102        @fwrite($fh, $out);
103        fclose($fh);
104        if($conf['fperm']) chmod($this->configFile, $conf['fperm']);
105        return true;
106    }
107
108    /**
109     * Header text for the cron config file
110     */
111    private function cronHeading()
112    {
113        $DOKU_URL = DOKU_URL;
114        return <<<OUTPUT
115<?php
116/*
117 * Siteexport Cron Job Configuration
118 * Auto-generated by siteexport
119 * Run for user: {$_SERVER['REMOTE_USER']}
120 */
121
122// Required to set the HTTP_HOST which is usually not set in CLI Environments
123\$_SERVER['HTTP_HOST'] = "{$_SERVER['HTTP_HOST']}";
124
125// This is not the nice way to inject another ROOT-URL, but we do not want to modify other stuff.
126if(!defined('DOKU_URL')) define('DOKU_URL', "{$DOKU_URL}");
127
128
129OUTPUT;
130    }
131
132    /**
133     * Footer Text for the cron config file
134     */
135    private function cronFooter()
136    {
137        return <<<OUTPUT
138
139// end of auto-generated content
140OUTPUT;
141    }
142
143    /**
144     * Checks if the settings file is writeable
145     */
146    public function canWriteSettings()
147    {
148        if ( !file_exists($this->configFile) && !$this->writeCronSettings() )
149        {
150            return false;
151        }
152
153        return is_writable($this->configFile);
154    }
155
156    /**
157     * Recursively walk through the settings and generate a nice looking string
158     * @param $settings Array of named settings
159     * @param $levelPrefix Prefix that will be build during recursion. It will contain a string for the named array depth
160     */
161    private function recurseSettingsToOut($settings, $levelPrefix = null)
162    {
163        if ( !is_array($settings) )
164        {
165            // If this is a value and the levelPrefix is not empty, print it out
166            if ( $levelPrefix == null || empty($settings) )
167            {
168                return '';
169            }
170
171            return '$settings' . $levelPrefix . ' = "' . trim($settings) . "\";\n";
172        }
173
174        $out = '';
175
176        // walk recursively through the content and giv it all back
177        foreach ($settings as $name => $value )
178        {
179            $out .= $this->recurseSettingsToOut($value, $levelPrefix . '["' . trim($name) . '"]');
180        }
181        return $out;
182    }
183
184    /**
185     * Checks if there is already a Cron Job for the given parameters
186     * @param $parameters
187     */
188    public function hasCronJobForParameters($parameters)
189    {
190        return array_key_exists($this->cronJobNameForParameters($parameters), $this->configuration);
191    }
192
193    /**
194     * returns a name for the parameters
195     * @param $parameters
196     */
197    public function cronJobNameForParameters($parameters)
198    {
199        return md5($parameters);
200    }
201}
202
203// ensure that the request comes from the cli
204if ( !array_key_exists('REMOTE_ADDR', $_SERVER) && 'cli' == php_sapi_name()) {
205    ini_set('memory_limit','512M');
206
207    // overriding this will lead to too many error messages
208    // error_reporting(E_ALL);
209
210    /**
211     * Cli Cron is responsible for doing the actual fetching of documentation
212     * @author gamma
213     *
214     */
215    class plugin_siteexport_cli_cron {
216
217        private $cronPlugin;
218        private $siteexportAjax;
219        public $error;
220
221        /**
222         * Instantiate and load plugin
223         */
224        public function __construct()
225        {
226            // Needs to go first, to initialize the config which holds some special treatment
227            $this->cronPlugin = new cron_plugin_siteexport();
228
229            // Load later to have the config up and running.
230            // the config needs to adjust some variables of the server
231            @require_once(DOKU_INC . 'inc/init.php');
232            @require_once(DOKU_INC . 'inc/common.php');
233            @require_once(DOKU_INC . 'inc/indexer.php');
234            @require_once(DOKU_INC . 'inc/io.php');
235            @require_once(DOKU_INC . 'inc/confutils.php');
236
237            if ( !$this->siteexportAjax = plugin_load('action', 'siteexport_ajax' ) ) {
238                $this->error = "Faild! Ajax Plugin not loaded\n";
239            }
240        }
241
242        /**
243         * let the plugin run!
244         */
245        public function run() {
246            global $ID;
247            global $INFO;
248
249            $originalREquest = $_REQUEST;
250
251            foreach ( $this->cronPlugin->configuration as $name => $config )
252            {
253                // retrieve parameters
254                list($id,$parameters) = explode('?', $config, 2);
255
256                $function = new siteexport_functions(false);
257                $_REQUEST = $function->parseStringToRequestArray($parameters, true);
258                unset($function);
259
260                $ID = $_REQUEST['id'] = cleanID($id); // re-set the ID
261                // $ID = getID();
262
263                // Lets start over!
264                $this->siteexportAjax->__init_functions();
265                $this->siteexportAjax->functions->settings->isCLI = true;
266                $this->siteexportAjax->functions->settings->isAuthed = true;
267                $INFO['perm'] = AUTH_DELETE; // Fake authentication
268
269                // Fake security Token if none given
270                if ( empty( $_REQUEST['sectok'] ) ) {
271                    $_REQUEST['sectok'] = $this->siteexportAjax->functions->getSecurityToken();
272                }
273
274                $data = $this->siteexportAjax->__get_siteexport_list_and_init_tocs($ID);
275
276                // If there is nothing in there - ignore. This may mean we have a valid cache
277                if ( count($data) == 0 ) {
278                    continue;
279                }
280
281                foreach ( $data as $site ) {
282
283                    // We want to create a specific file! - have to reset it every time in here
284                    // $_REQUEST['pattern'] = $name;
285                    $status = $this->siteexportAjax->__siteexport_add_site($site['id']);
286                }
287
288                $this->siteexportAjax->functions->checkIfCacheFileExistsForFileWithPattern($this->siteexportAjax->functions->getCacheFileNameForPattern(), $name);
289
290                // Wat zum geier?
291                $this->siteexportAjax->cleanCacheFiles();
292            }
293        }
294    }
295
296    $cron = new plugin_siteexport_cli_cron();
297    if ( empty($cron->error) )
298    {
299        $cron->run();
300    } else
301    {
302        echo <<<OUTPUT
303************************************************************************
304* ERROR                                                                *
305************************************************************************
306
307        {$cron->error}
308************************************************************************
309
310
311OUTPUT;
312    }
313}
314
315?>