diff --git a/ajax/cronservice/getStatus.php b/ajax/cronservice/getStatus.php new file mode 100644 index 0000000000000000000000000000000000000000..8c5d208f2c87d22b72cc8484b85f0340ceb6f0b2 --- /dev/null +++ b/ajax/cronservice/getStatus.php @@ -0,0 +1,17 @@ +<?php + +/** + * Gets the current Status for this instance + * + * @return string - Returns the status + */ +QUI::$Ajax->registerFunction( + 'package_quiqqer_cron_ajax_cronservice_getStatus', + function () { + $CronService = new \QUI\Cron\CronService(); + + return $CronService->getStatus(); + }, + array(), + '' +); diff --git a/ajax/cronservice/revokeRegistration.php b/ajax/cronservice/revokeRegistration.php new file mode 100644 index 0000000000000000000000000000000000000000..99f6f6270fac8d83cfb003452d8802256b726f52 --- /dev/null +++ b/ajax/cronservice/revokeRegistration.php @@ -0,0 +1,15 @@ +<?php + +/** + * Revokes a registration on the cronservice server. + * + */ +QUI::$Ajax->registerFunction( + 'package_quiqqer_cron_ajax_cronservice_revokeRegistration', + function () { + $CronService = new \QUI\Cron\CronService(); + $CronService->revokeRegistration(); + }, + array(), + '' +); diff --git a/ajax/cronservice/sendRegistration.php b/ajax/cronservice/sendRegistration.php new file mode 100644 index 0000000000000000000000000000000000000000..91ab2b7beff5aad76790d095c97ec7dc2fcff51f --- /dev/null +++ b/ajax/cronservice/sendRegistration.php @@ -0,0 +1,16 @@ +<?php + +/** + * Sends a registration to the cronservice server. + * + * + */ +QUI::$Ajax->registerFunction( + 'package_quiqqer_cron_ajax_cronservice_sendRegistration', + function ($email) { + $CronService = new \QUI\Cron\CronService(); + $CronService->register($email); + }, + array('email'), + '' +); diff --git a/bin/CronServiceWindow.css b/bin/CronServiceWindow.css new file mode 100644 index 0000000000000000000000000000000000000000..07e20ae99496e3f9c3c4cb35cefa298f442cad16 --- /dev/null +++ b/bin/CronServiceWindow.css @@ -0,0 +1,82 @@ + +.quiqqer-cron-cronservicewindow-btn-openRegistration { + margin : 30px auto 0 auto; + float : right; +} + +.quiqqer-cron-cronserviceWindow h2 { + font-weight : normal; + margin-bottom : 10px; +} + +.quiqqer-cron-cronservicewindow-title { + padding-bottom : 10px; + text-align : center; +} + +.quiqqer-cron-cronservicewindow-title span { + clear : both; + display : block; +} + +.quiqqer-cron-cronservicewindow-title .fa { + font-size : 60px; +} + +.quiqqer-cron-cronservicewindow-section { + margin : 15px auto; +} + +.quiqqer-cron-cronservicewindow-buttons { + text-align : center; + margin-top : 40px; + width : 100%; +} + +.quiqqer-cron-cronservicewindow-stat-title { + font-weight : bold; +} + +.quiqqer-cron-cronservice-table-stats { + width : 100%; +} + +.quiqqer-cron-cronservice-table-stats td { + width : 50%; +} + +.quiqqer-cron-cronservicewindow-stat-negative { + color : red; +} + +.quiqqer-cron-cronservicewindow-stat-positive { + color : green; +} + +/* Registration Sheet */ + +.quiqqer-cron-cronservicewindow-registration { + padding : 20px; +} + +.quiqqer-cron-cronservicewindow-registration-title { + border-bottom : 1px solid #eee; + padding-bottom : 10px; +} + +.quiqqer-cron-cronservicewindow-registration-lbl-email { + font-weight : bold; + padding : 2px; + width : 100%; +} + +.quiqqer-cron-cronservicewindow-registration-txt-email { + width : 100%; + margin-top : 6px; +} + +.quiqqer-cron-cronservicewindow-btn-register { + margin-top : 20px; + float : right; +} + diff --git a/bin/CronServiceWindow.html b/bin/CronServiceWindow.html new file mode 100644 index 0000000000000000000000000000000000000000..3d276447969a0f2ce8bfa438ff145abb26ecc9db --- /dev/null +++ b/bin/CronServiceWindow.html @@ -0,0 +1,56 @@ +<h1 class="quiqqer-cron-cronservicewindow-title"> + <span class="fa fa-cloud"></span> + <span>{{cron_window_cronservice_content_title}}</span> +</h1> + +<div class="quiqqer-cron-cronservicewindow-section"> + <h2>{{cron_window_cronservice_content_about_title}}</h2> + <p> + {{cron_window_cronservice_content_about_text}} + </p> +</div> + +<div class="quiqqer-cron-cronservicewindow-section"> + <h2>{{cron_window_cronservice_content_status_title}}</h2> + + {{cron_window_cronservice_content_status_text}} + + <table class="quiqqer-cron-cronservice-table-stats"> + <tr> + <td> + <span class="quiqqer-cron-cronservicewindow-stat-title"> + {{cron_window_cronservice_content_register_lbl_stats_status}} + </span> + </td> + <td> + <span class="{{#active}}quiqqer-cron-cronservicewindow-stat-positive{{/active}}{{^active}}quiqqer-cron-cronservicewindow-stat-negative{{/active}}"> + {{statusText}} + </span> + </td> + </tr> + {{#registered}} + <tr> + <td> + <span class="quiqqer-cron-cronservicewindow-stat-title"> + {{cron_window_cronservice_content_register_lbl_stats_errors}} + </span> + </td> + <td> + {{statusErrors}} + </td> + </tr> + <tr> + <td> + <span class="quiqqer-cron-cronservicewindow-stat-title"> + {{cron_window_cronservice_content_register_lbl_stats_lastExecution}} + </span> + </td> + <td> + {{statusLastExecution}} + </td> + </tr> + {{/registered}} + </table> +</div> + +<div class="quiqqer-cron-cronservicewindow-buttons"></div> \ No newline at end of file diff --git a/bin/CronServiceWindow.js b/bin/CronServiceWindow.js new file mode 100644 index 0000000000000000000000000000000000000000..0a10bbcdac6fe0cd84e3904bcf77aaf1e87c99e1 --- /dev/null +++ b/bin/CronServiceWindow.js @@ -0,0 +1,220 @@ +/** + * + */ +define('package/quiqqer/cron/bin/CronServiceWindow', [ + + 'qui/QUI', + 'qui/controls/windows/Popup', + 'qui/controls/buttons/Button', + 'Mustache', + 'Locale', + 'Ajax', + 'qui/controls/desktop/panels/Sheet', + + 'text!package/quiqqer/cron/bin/CronServiceWindow.html', + 'text!package/quiqqer/cron/bin/CronServiceWindowRegistration.html', + 'css!package/quiqqer/cron/bin/CronServiceWindow.css' + +], function (QUI, QUIPopup, QUIButton, Mustache, QUILocale, QUIAjax, QUISheets, template, registrationTemplate) { + "use strict"; + + var lg = 'quiqqer/cron'; + + return new Class({ + + Extends: QUIPopup, + Type : 'package/quiqqer/cron/bin/CronServiceWindow', + + Binds: [ + '$onSubmit', + '$onOpen', + 'showRegistration' + ], + + options: { + title : QUILocale.get(lg, 'cron.window.cronservice.title'), + icon : 'fa fa-cloud', + maxWidth : 400, + maxHeight: 600, + autoclose: false, + buttons : false + }, + + initialize: function (options) { + this.parent(options); + + this.registered = false; + + this.addEvents({ + onOpen: this.$onOpen + }); + }, + + $onOpen: function () { + var Content = this.getContent(); + + Content.set('html', ''); + Content.addClass('quiqqer-cron-cronserviceWindow'); + + this.refresh(); + }, + + /** + * refresh + */ + refresh: function () { + var self = this, + Content = this.getContent(); + + this.Loader.show(); + + QUIAjax.get('package_quiqqer_cron_ajax_cronservice_getStatus', function (result) { + var status = result; + + var statusText = QUILocale.get(lg, 'cron.window.cronservice.status.text.unregistered'); + if (status['status'] == 1) { + statusText = QUILocale.get(lg, 'cron.window.cronservice.status.text.registered'); + } + if (status['status'] == 2) { + statusText = QUILocale.get(lg, 'cron.window.cronservice.status.text.inactive'); + } + + + Content.set('html', Mustache.render(template, { + cron_window_cronservice_content_title : QUILocale.get(lg, 'cron.window.cronservice.content.title'), + cron_window_cronservice_content_about_title : QUILocale.get(lg, 'cron.window.cronservice.content.about.title'), + cron_window_cronservice_content_about_text : QUILocale.get(lg, 'cron.window.cronservice.content.about.text'), + cron_window_cronservice_content_status_title : QUILocale.get(lg, 'cron.window.cronservice.content.status.title'), + cron_window_cronservice_content_status_text : QUILocale.get(lg, 'cron.window.cronservice.content.status.text'), + cron_window_cronservice_content_btn_unregister : QUILocale.get(lg, 'cron.window.cronservice.content.register.btn.unregister'), + cron_window_cronservice_content_btn_register : QUILocale.get(lg, 'cron.window.cronservice.content.btn.register'), + cron_window_cronservice_content_register_lbl_stats_status : QUILocale.get(lg, 'cron.window.cronservice.content.register.lbl.stats.status'), + cron_window_cronservice_content_register_lbl_stats_errors : QUILocale.get(lg, 'cron.window.cronservice.content.register.lbl.stats.errors'), + cron_window_cronservice_content_register_lbl_stats_lastExecution: QUILocale.get(lg, 'cron.window.cronservice.content.register.lbl.stats.lastExecution'), + statusText : statusText, + status : status['status'], + statusErrors : status['current_failures'], //== 0 ? "0": status['errors'].toString(), + statusLastExecution : status['last_execution'], + registered : (status['status'] != 0), + active : (status['status'] == 1), + inactive : (status['status'] == 2) + })); + + self.registered = (status['status'] != 0); + + var Buttons = Content.getElement('.quiqqer-cron-cronservicewindow-buttons'); + + // get the button text : register or unregister + var btnText = QUILocale.get(lg, 'cron.window.cronservice.content.btn.register'); + if (self.registered) { + btnText = QUILocale.get(lg, 'cron.window.cronservice.content.btn.unregister'); + } + + new QUIButton({ + text : btnText, + textimage: 'fa fa-arrow-right', + events : { + onClick: function (Button) { + if (!self.registered) { + self.showRegistration(); + return; + } + Button.setAttribute('text', QUILocale.get('quiqqer/cron', 'cron.window.cronservice.content.btn.unregister.confirm')); + if (Button.getAttribute('clickcnt') == 1) { + self.unregister().then(function () { + self.refresh(); + }); + } + Button.setAttribute('clickcnt', 1); + } + }, + styles : { + 'float': 'none', + margin : '0 auto', + width : 200 + } + }).inject(Buttons); + + + self.Loader.hide(); + }, { + 'package': lg, + 'onError': function () { + self.Loader.hide(); + } + }); + }, + + /** + * Opens the registration sheet + */ + showRegistration: function () { + var self = this; + + new QUISheets({ + header : true, + icon : 'fa fa-cloud', + title : QUILocale.get(lg, 'cron.window.cronservice.title'), + buttons: false, + events : { + onOpen: function (Sheet) { + var Content = Sheet.getContent(); + + Content.set('html', Mustache.render(registrationTemplate, { + cron_window_cronservice_registration_title : QUILocale.get(lg, 'cron.window.cronservice.registration.title'), + cron_window_cronservice_content_register_txt_email_title : QUILocale.get(lg, 'cron.window.cronservice.content.register.txt.email.title'), + cron_window_cronservice_content_register_placeholder_email: QUILocale.get(lg, 'cron.window.cronservice.content.register.placeholder.email'), + cron_window_cronservice_content_btn_register : QUILocale.get(lg, 'cron.window.cronservice.registration.title') + })); + + var Email = Content.getElement('.quiqqer-cron-cronservicewindow-registration-txt-email'); + + Content.getElement('.quiqqer-cron-cronservicewindow-btn-register').addEvent('click', function () { + self.Loader.show(); + self.register(Email.value).then(function () { + self.refresh(); + Sheet.destroy(); + }).catch(function () { + self.Loader.hide(); + }); + }); + }, + + onClose: function (Sheet) { + Sheet.destroy(); + } + } + }).inject(this.$Elm).show(); + }, + + /** + * Register a email to the cron service + * + * @param {String} email + * @returns {Promise} + */ + register: function (email) { + return new Promise(function (resolve, reject) { + QUIAjax.post('package_quiqqer_cron_ajax_cronservice_sendRegistration', resolve, { + 'package': lg, + 'email' : email, + onError : reject + }); + }); + }, + + /** + * Unregister a email to the cron service + * + * @returns {Promise} + */ + unregister: function () { + return new Promise(function (resolve, reject) { + QUIAjax.get('package_quiqqer_cron_ajax_cronservice_revokeRegistration', resolve, { + 'package': lg, + onError : reject + }); + }); + } + }); +}); diff --git a/bin/CronServiceWindowRegistration.html b/bin/CronServiceWindowRegistration.html new file mode 100644 index 0000000000000000000000000000000000000000..1382e6ab701e0b9fd646fa87f3adccadd4d49bd0 --- /dev/null +++ b/bin/CronServiceWindowRegistration.html @@ -0,0 +1,25 @@ +<div class="quiqqer-cron-cronservicewindow-registration"> + <h1 class="quiqqer-cron-cronservicewindow-registration-title"> + {{cron_window_cronservice_registration_title}} + </h1> + <form action="" method="POST"> + <label + class="quiqqer-cron-cronservicewindow-registration-lbl-email" + for="quiqqer-cron-cronservicewindow-registration-txt-email" + > + {{cron_window_cronservice_content_register_txt_email_title}} + </label> + <input + id="quiqqer-cron-cronservicewindow-registration-txt-email" + type="text" + name="email" + required="required" + placeholder="{{cron_window_cronservice_content_register_placeholder_email}}" + class="quiqqer-cron-cronservicewindow-registration-txt-email" + /> + <div class="quiqqer-cron-cronservicewindow-btn-register qui-button"> + <span class="fa fa-check"></span> + <span>{{cron_window_cronservice_content_btn_register}}</span> + </div> + </form> +</div> \ No newline at end of file diff --git a/bin/Manager.js b/bin/Manager.js index a6403fbff0e4b63e62ed80c51299c27a848a3f3e..b7ddb5bb1fec560ca9f0f67a5c9912fe3b836b63 100644 --- a/bin/Manager.js +++ b/bin/Manager.js @@ -176,6 +176,21 @@ define('package/quiqqer/cron/bin/Manager', [ this.getButtons('delete').disable(); + this.addButton(new QUIButtonSeperator()); + this.addButton( + new QUIButton({ + name : 'cronservice', + text : QUILocale.get(lg, 'cron.panel.manager.btn.cronservice.register'), + textimage: 'fa fa-cloud', + events : { + onClick: function () { + self.registerCronservice(); + } + } + }) + ); + + var Content = this.getContent(), Container = new Element('div', { @@ -465,6 +480,16 @@ define('package/quiqqer/cron/bin/Manager', [ require(['package/quiqqer/cron/bin/History'], function (Panel) { new Panel().inject(self.getParent()); }); + }, + + /** + * Opens the Cronservice registration + */ + registerCronservice: function () { + require(['package/quiqqer/cron/bin/CronServiceWindow'], function (CronServiceWindow) { + var csWindow = new CronServiceWindow(); + csWindow.open(); + }); } }); }); \ No newline at end of file diff --git a/database.xml b/database.xml index 1e8c91341a462c5f974751df2853ce38daa3a448..daf288184fad34e5dcd36c622ea3ebdc234fba8e 100644 --- a/database.xml +++ b/database.xml @@ -21,6 +21,12 @@ <field type="INT( 11 ) NOT NULL">uid</field> <field type="DATETIME NULL">lastexec</field> </table> + + <table name="cron_cronservice"> + <field type="INT( 3 ) NOT NULL">cronid</field> + <field type="INT( 11 ) NOT NULL">uid</field> + <field type="DATETIME NULL">lastexec</field> + </table> </global> </database> diff --git a/locale.xml b/locale.xml index d33d8bb28b98c0f0f2ff4c4a3a3b4af1ccdfd054..430f40986ce7acbd754614b404cea7de2f2a8b60 100644 --- a/locale.xml +++ b/locale.xml @@ -58,6 +58,22 @@ <de><![CDATA[Der Administrator bekommt eine Nachricht wenn die Crons die letzten 24h nicht liefen.]]></de> <en><![CDATA[The administrator receives a message when the Cron did not run the last 24 hours]]></en> </locale> + <locale name="exception.registration.empty.domain"> + <de><![CDATA[Es muss eine Domain angegeben sein]]></de> + <en><![CDATA[Domain can not be empty]]></en> + </locale> + <locale name="exception.registration.empty.email"> + <de><![CDATA[Es muss eine Email angegeben sein.]]></de> + <en><![CDATA[An email must be given.]]></en> + </locale> + <locale name="exception.registration.empty.packageDir"> + <de><![CDATA[Konnte den "package" Pfad nicht auslesen!]]></de> + <en><![CDATA[Could not parse the "package" folder path.]]></en> + </locale> + <locale name="cron.window.cronservice.status.text.last_execution.never"> + <de><![CDATA[Nie]]></de> + <en><![CDATA[Never]]></en> + </locale> </groups> <groups name="quiqqer/cron" datatype="js"> <locale name="cron.id"> @@ -146,6 +162,107 @@ <de><![CDATA[Aufgabenverlauf]]></de> <en><![CDATA[Cron history]]></en> </locale> + <locale name="cron.panel.manager.btn.cronservice.register"> + <de><![CDATA[Cronservice]]></de> + <en><![CDATA[Cronservice]]></en> + </locale> + + <locale name="cron.window.cronservice.title"> + <de><![CDATA[Cronservice]]></de> + <en><![CDATA[Cronservice]]></en> + </locale> + <locale name="cron.window.cronservice.btn.cancel"> + <de><![CDATA[Abbrechen]]></de> + <en><![CDATA[Cancel]]></en> + </locale> + <locale name="cron.window.cronservice.btn.register"> + <de><![CDATA[Registrieren]]></de> + <en><![CDATA[Register]]></en> + </locale> + <locale name="cron.window.cronservice.content.title"> + <de><![CDATA[Cronservice]]></de> + <en><![CDATA[Cronservice]]></en> + </locale> + <locale name="cron.window.cronservice.content.about.title"> + <de><![CDATA[Was ist das?]]></de> + <en><![CDATA[About]]></en> + </locale> + <locale name="cron.window.cronservice.content.about.text"> + <de><![CDATA[Der QUIQQER Cronservice ermöglicht es Crons auf Systemen auszuführen, die nativ keine Crons ausführen können. +Realisiert wird dies durch einen Server, an dem sich QUIQQER-SYteme anmelden können, welcher wiederrum regelmäßig die Crons der angemeldeten Systeme anstoßt. +Dies kann vorallem auf Shared-Hostings von großem Nutzen sein.]]></de> + <en><![CDATA[The QUIQQER cronservice enables systems withou native cronfunctionality to execute the QUIQQER crons anyway. +This is works with an external server on which QUIQQER systems can register themselves. This server will start the scheduled crons of all registered QUIQQER systems regularely. +]]></en> + </locale> + <locale name="cron.window.cronservice.content.status.title"> + <de><![CDATA[Status]]></de> + <en><![CDATA[State]]></en> + </locale> + <locale name="cron.window.cronservice.content.status.text"> + <de><![CDATA[Hier können Sie den Status Ihrer Registrierung verfolgen :]]></de> + <en><![CDATA[You can check the state of your registration here :]]></en> + </locale> + <locale name="cron.window.cronservice.content.btn.register"> + <de><![CDATA[Registrieren]]></de> + <en><![CDATA[Register]]></en> + </locale> + <locale name="cron.window.cronservice.content.register.title"> + <de><![CDATA[Registrieren]]></de> + <en><![CDATA[Register]]></en> + </locale> + <locale name="cron.window.cronservice.content.register.placeholder.email"> + <de><![CDATA[Email]]></de> + <en><![CDATA[Email]]></en> + </locale> + <locale name="cron.window.cronservice.registration.title"> + <de><![CDATA[Registration]]></de> + <en><![CDATA[Registration]]></en> + </locale> + <locale name="cron.window.cronservice.content.register.txt.email.title"> + <de><![CDATA[Email]]></de> + <en><![CDATA[Email]]></en> + </locale> + <locale name="cron.window.cronservice.content.register.btn.register"> + <de><![CDATA[Registrieren]]></de> + <en><![CDATA[Register]]></en> + </locale> + <locale name="cron.window.cronservice.content.register.btn.unregister"> + <de><![CDATA[Abmelden]]></de> + <en><![CDATA[Unregister]]></en> + </locale> + <locale name="cron.window.cronservice.status.text.inactive"> + <de><![CDATA[Inaktiv]]></de> + <en><![CDATA[Inactive]]></en> + </locale> + <locale name="cron.window.cronservice.status.text.registered"> + <de><![CDATA[Aktiv]]></de> + <en><![CDATA[Active]]></en> + </locale> + <locale name="cron.window.cronservice.status.text.unregistered"> + <de><![CDATA[Nicht registriert]]></de> + <en><![CDATA[Not registered]]></en> + </locale> + <locale name="cron.window.cronservice.content.register.lbl.stats.status"> + <de><![CDATA[Status: ]]></de> + <en><![CDATA[Status: ]]></en> + </locale> + <locale name="cron.window.cronservice.content.register.lbl.stats.errors"> + <de><![CDATA[Fehlerzahl: ]]></de> + <en><![CDATA[Errorcount: ]]></en> + </locale> + <locale name="cron.window.cronservice.content.register.lbl.stats.lastExecution"> + <de><![CDATA[Letzte Ausführung: ]]></de> + <en><![CDATA[Last execution: ]]></en> + </locale> + <locale name="cron.window.cronservice.content.btn.unregister.confirm"> + <de><![CDATA[Sind Sie sicher?]]></de> + <en><![CDATA[Are you sure?]]></en> + </locale> + <locale name="cron.window.cronservice.content.btn.unregister"> + <de><![CDATA[Registrierung entfernen]]></de> + <en><![CDATA[Unregister]]></en> + </locale> <locale name="permission.quiqqer.cron._header"> <de><![CDATA[Aufgaben / Tasks]]></de> @@ -175,6 +292,5 @@ <de><![CDATA[Darf Aufgaben / Tasks deaktivieren.]]></de> <en><![CDATA[Can deactivate tasks.]]></en> </locale> - </groups> </locales> \ No newline at end of file diff --git a/src/QUI/Cron/CronService.php b/src/QUI/Cron/CronService.php new file mode 100644 index 0000000000000000000000000000000000000000..0d1edc82d872b697957ea4928e182d976d4e7b88 --- /dev/null +++ b/src/QUI/Cron/CronService.php @@ -0,0 +1,244 @@ +<?php + +namespace QUI\Cron; + +use QUI; +use QUI\System\Log; + +class CronService +{ + + const CRONSERVICE_URL = "https://cron.quiqqer.com"; + + private $domain; + private $https; + private $packageDir; + + + public function __construct() + { + $host = QUI::$Conf->get("globals", "host"); + $cms_dir = QUI::$Conf->get("globals", "cms_dir"); + $opt_dir = QUI::$Conf->get("globals", "opt_dir"); + $url_dir = QUI::$Conf->get("globals", "url_dir"); + + // Parse Domain and protocol + if (strpos($host, "https://") !== false) { + $this->https = true; + $this->domain = str_replace("https://", "", $host); + } elseif (strpos($host, "http://") !== false) { + $this->https = false; + $this->domain = str_replace("http://", "", $host); + } else { + $this->https = false; + $this->domain = $host; + } + + // Parse Package dir + $this->packageDir = $url_dir . str_replace($cms_dir, "", $opt_dir); + } + + /** + * Will register this quiqqer instance. + * + * @param $email - Email used for communication. Must be valid. + */ + public function register($email) + { + $this->sendRegistrationRequest($this->domain, $email, $this->packageDir, $this->https); + } + + /** + * Gets the status of the given domain. + * + * Returnformat : + * array( + * 'status' => 0, (0=unregistered; 1=active; 2=inactive) + * 'current_failures' => int, + * 'total_failures' => int, + * 'last_execution' => string (mysql dateformat | Localized 'never') + * ) + * + * @return mixed + */ + public function getStatus() + { + $status = $this->makeServerAjaxCall('package_pcsg_cronservice_ajax_getStatus', array( + 'domain' => $this->domain + )); + + if (empty($status['last_execution'])) { + $status['last_execution'] = QUI::getLocale()->get( + 'quiqqer/cron', + 'cron.window.cronservice.status.text.last_execution.never' + ); + } + + return $status; + } + + /** + * Revoked the registration for this quiqqer instance + */ + public function revokeRegistration() + { + $token = $this->readRevokeToken(); + + $this->makeServerAjaxCall('package_pcsg_cronservice_ajax_revokeRegistration', array( + 'domain' => $this->domain, + 'token' => $token + )); + } + + /** + * Sends an ajax request to the cronservice server. + * + * @param $domain - The domain to be registered. Example : example.org + * @param $email - The Email that should be used for communication. + * @param $packageDir - The package url dir + * @param $https - wether or not http secure should be used to call the cron.php + * @throws Exception + */ + private function sendRegistrationRequest($domain, $email, $packageDir, $https) + { + if (empty($domain)) { + throw new Exception(array("quiqqer/cron", "exception.registration.empty.domain")); + } + + if (empty($email)) { + throw new Exception(array("quiqqer/cron", "exception.registration.empty.email")); + } + + if (empty($packageDir)) { + throw new Exception(array("quiqqer/cron", "exception.registration.empty.packageDir")); + } + + + $url = self::CRONSERVICE_URL . "/admin/ajax.php?" . + "_rf=" . urlencode("[\"package_pcsg_cronservice_ajax_register\"]") . + "&package=" . urlencode("pcsg/cronservice") . + "&lang=" . QUI::getUserBySession()->getLang() . + "&domain=" . urlencode($domain) . + "&email=" . urlencode($email) . + "&packageDir=" . urlencode($packageDir) . + "&https=" . ($https ? "1" : "0") . + "&user=" . QUI::getUserBySession()->getName(); + + + $curl = curl_init(); + curl_setopt_array($curl, array( + CURLOPT_RETURNTRANSFER => 1, + CURLOPT_URL => $url, + CURLOPT_USERAGENT => 'QUIQQER' + )); + + $response = curl_exec($curl); + $response = substr($response, 9, -10); + $data = json_decode($response, true); + if (json_last_error() != JSON_ERROR_NONE) { + Log::addDebug($response); + throw new Exception(json_last_error_msg()); + } + + if (!isset($data['package_pcsg_cronservice_ajax_register']['result'])) { + throw new Exception("Something went wrong!"); + } + + $data = $data['package_pcsg_cronservice_ajax_register']['result']; + if (!isset($data['status']) || $data['status'] != 1) { + Log::addDebug($response); + Log::writeRecursive($data); + if (isset($data['message'])) { + throw new Exception($data['message']); + } + + throw new Exception("Something went wrong!"); + } + + + $revokeCode = $data['revokeCode']; + $this->saveRevokeToken($revokeCode); + + curl_close($curl); + } + + /** + * Calls the given ajax function on the Cronservice server and returns its output + * @param $function - Ajax function name + * @param $params - Params to pass + * @return mixed + * @throws QUI\Exception + */ + private function makeServerAjaxCall($function, $params) + { + $url = self::CRONSERVICE_URL . "/admin/ajax.php?" . + "_rf=" . urlencode('["' . $function . '"]') . + "&package=" . urlencode("pcsg/cronservice") . + "&lang=" . QUI::getUserBySession()->getLang(); + + foreach ($params as $param => $value) { + $url .= '&' . $param . '=' . urlencode($value); + } + + $curl = curl_init(); + curl_setopt_array($curl, array( + CURLOPT_RETURNTRANSFER => 1, + CURLOPT_URL => $url, + CURLOPT_USERAGENT => 'QUIQQER' + )); + + $response = curl_exec($curl); + + curl_close($curl); + + // Process raw ajax response + $response = substr($response, 9, -10); + $response = json_decode($response, true); + + + if (isset($response[$function]['Exception'])) { + throw new QUI\Exception($response[$function]['Exception']['message']); + } + + return $response[$function]['result']; + } + + /** + * Saves the revoke token into a file + * @param $token + */ + private function saveRevokeToken($token) + { + $varDir = QUI::getPackage('quiqqer/cron')->getVarDir() . '/cronservice'; + $fileName = $varDir . '/.revoketoken'; + + if (!is_dir($varDir)) { + mkdir($varDir, 0700, true); + } + + file_put_contents($fileName, $token); + } + + /** + * Reads the revoke token from the filesystem + * @return string + * @throws Exception + */ + private function readRevokeToken() + { + $varDir = QUI::getPackage('quiqqer/cron')->getVarDir() . '/cronservice'; + $fileName = $varDir . '/.revoketoken'; + + if (!file_exists($fileName)) { + throw new Exception("Tokenfile not present"); + } + + $token = file_get_contents($fileName); + + if ($token === false) { + throw new Exception("Could not read tokenfile."); + } + + return $token; + } +} diff --git a/src/QUI/Cron/Exception.php b/src/QUI/Cron/Exception.php new file mode 100644 index 0000000000000000000000000000000000000000..e185f57b189361eba8fe3d037ef9c16537cd40c8 --- /dev/null +++ b/src/QUI/Cron/Exception.php @@ -0,0 +1,10 @@ +<?php + +namespace QUI\Cron; + +use QUI; + +class Exception extends QUI\Exception +{ + +}