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