83f15d69755585c3a825c3eccf2d654fc6578dadb7e05475
, bei Redaxo 4 Instanzen legacy
+project_manager_plus_server_param = Parameter
+project_manager_plus_server_param_notice = Optionale Paramenter, z.B. param1=value1,param2=value2
+project_manager_plus_server_ssl = SSL Verbindung
+project_manager_plus_server_tags = Tags
+project_manager_plus_server_maintenance = Wartungsvertrag?
+project_manager_plus_server_maintenance_short = WV
+
+#detail
+project_manager_plus_server_project_detail = Details
+project_manager_plus_server_project_choose = Projekt wählen
+
+project_manager_plus_cronjob_favicon_name = Projekt Manager: Hole Favicon
+project_manager_plus_cronjob_data_name = Projekt Manager: Hole Domaindaten
+
+perm_general_project_manager_plus_server[] = project_manager_plus_server[] - Rechte für Projekt Manager Server Konfiguration
+
+
+#config
+project_manager_plus_server_title = Einstellungen
+project_manager_plus_server_min_headline = Mindestanforderungen
+project_manager_plus_server_php_min = PHP Version
+project_manager_plus_server_cms_4_min = Redaxo 4 Version
+project_manager_plus_server_cms_min = Redaxo 5 Version
+project_manager_plus_server_config_saved_successful = Einstellungen gespeichert!
+project_manager_plus_server_min_color = Farbe
+project_manager_plus_server_color_notice = Farbe bitte als HEX #F1F1F1 oder als RGBA angeben rgba(0,0,0,0.1)
+project_manager_plus_server_configuration = Einstellungen
+project_manager_plus_server_skip_addon = Addons ausschließen
+project_manager_plus_server_skip_addon_version = Versionen ausschließen
+project_manager_plus_server_skip_addon_notice = Addon wird bei der Prüfung nicht berücksichtigt. z.B. structure_tweaks, modulsammlung
+project_manager_plus_server_skip_addon_version_notice = Addonversion wird bei der Prüfung nicht berücksichtigt. z.B. beta, dev, rc
+
+
+#validate
+no_name_defined = Kein Projektname angegeben!
+no_domain_defined = Keine Domain angegeben!
+
+# Client
+
+
+client_navigation_title = Navigation [ main_navi.md ]
+client_content_title = Inhalt [ {0} ]
+
+client_noparser = Kein Markdown-Parser vorhanden! Bitte zuerst einen Parser installieren (Addon markitup oder textile)
+
+client_navinotfound = Navigations-Datei {0} wurde nicht gefunden!AIzaSyCp0Em_UPY78238es-9CZViEbq7CB_zcFBs
+project_manager_plus_pagespeed_domain_norows_message = Kein Projekt vorhanden
+project_manager_plus_cronjob_pagespeed_name = Projekt Manager: Hole Pagespeed Daten
+
+
+project_manager_plus_pagespeed_name = Projektname
+project_manager_plus_pagespeed_domain = Domain
+project_manager_plus_pagespeed_updatedate = Letzte Änderung
+project_manager_plus_pagespeed_logdate = Letzter Datenfetch
+project_manager_plus_pagespeed_domain_norows_message = Keine Einträge vorhanden
+
+perm_general_project_manager_plus_pagespeed[] = project_manager_plus_pagespeed[] - Rechte für Projekt Manager PageSpeed
+
+# Hosting
+
+project_manager_plus_hosting_menu_entry = Hosting
+
+project_manager_plus_hosting_projects = Projekte
+project_manager_plus_hosting_title = Übersicht
+project_manager_plus_hosting_domain_norows_message = Kein Projekt vorhanden
+project_manager_plus_cronjob_hosting_name = Projekt Manager: Hole Hosting Daten
+
+project_manager_plus_hosting_name = Projektname
+project_manager_plus_hosting_domain = Domain
+project_manager_plus_hosting_createdate = Letzte Änderung
+project_manager_plus_hosting_ip = IPv4-Adresse
+project_manager_plus_hosting_is_ssl = SSL
+project_manager_plus_hosting_organisation = Organisation
+project_manager_plus_hosting_isp = ISP
+project_manager_plus_hosting_domain_norows_message = Keine Einträge vorhanden
+project_manager_plus_hosting_validTo = Zertifikat Enddatum
+project_manager_plus_hosting_validFrom = Zertifikat Startdatum
+
+perm_general_project_manager_plus_hosting[] = project_manager_plus_hosting[] - Rechte für Projekt Manager Hosting
diff --git a/lang/en_gb.lang b/lang/en_gb.lang
deleted file mode 100644
index d4bbb64..0000000
--- a/lang/en_gb.lang
+++ /dev/null
@@ -1,13 +0,0 @@
-project_manager_title = Project Manager
-
-project_manager_main = Info
-
-project_manager_navigation = Navigation
-project_manager_docs = Help
-project_manager_config = Settings
-
-project_manager_config_save = Save
-project_manager_config_saved = Saved!
-save = Save
-
-perm_general_project_manager[] = project_manager[] - Perms for Project Manager
\ No newline at end of file
diff --git a/lang/es_es.lang b/lang/es_es.lang
deleted file mode 100644
index 80d9a3a..0000000
--- a/lang/es_es.lang
+++ /dev/null
@@ -1,14 +0,0 @@
-project_manager_title = Gestor de proyectos
-
-project_manager_main = Información
-
-project_manager_navigation = Navegación
-project_manager_docs = Ayuda
-project_manager_config = Ajustes
-
-project_manager_config_save = Guardar
-project_manager_config_saved = Guardado!
-save = Guardar
-
-perm_general_project_manager[] = project_manager[] - Derechos
-perm_general_project_manager[config] = project_manager[config] - Derechos para la configuración
\ No newline at end of file
diff --git a/lang/pt_br.lang b/lang/pt_br.lang
deleted file mode 100644
index 3f183bc..0000000
--- a/lang/pt_br.lang
+++ /dev/null
@@ -1,13 +0,0 @@
-project_manager_title = Gestor de projeto
-
-project_manager_main = Info
-
-project_manager_navigation = Navegação
-project_manager_docs = Ajuda
-project_manager_config = Configurações
-
-project_manager_config_save = Guardar
-project_manager_config_saved = Guardado!
-
-perm_general_project_manager[] = project_manager[] - Direitos
-perm_general_project_manager[config] = project_manager[config] - Direitos de configurações
\ No newline at end of file
diff --git a/lang/sv_se.lang b/lang/sv_se.lang
deleted file mode 100644
index a049f33..0000000
--- a/lang/sv_se.lang
+++ /dev/null
@@ -1,13 +0,0 @@
-project_manager_title = Projektledare
-
-project_manager_main = Info
-
-project_manager_navigation = Navigering
-project_manager_docs = Hjälp
-project_manager_config = Konfiguraion
-
-project_manager_config_save = Spara
-project_manager_config_saved = Inställningarna har sparats!
-save = Spara
-
-perm_general_project_manager[] = project_manager[] - Rättigheter
\ No newline at end of file
diff --git a/lib/Api/Manager.php b/lib/Api/Manager.php
new file mode 100644
index 0000000..539e902
--- /dev/null
+++ b/lib/Api/Manager.php
@@ -0,0 +1,164 @@
+getProperty('version');
+ $params['client_version'] = rex_addon::get('project_manager_plus')->getProperty('version');
+ $params['rex_version'] = rex::getVersion();
+ $params['cms'] = "REDAXO";
+ $params['cms_version'] = rex::getVersion();
+ $params['rex_url_backend'] = rex_url::backend();
+ $params['php_version'] = phpversion();
+ $params['mysql_version'] = rex_sql::getServerVersion();
+ $params['status'] = 1;
+ $params['debug'] = rex::isDebugMode();
+
+ # / REDAXO / SERVER / ALLGEMEIN
+
+ # ADDONS
+
+ $rex_addons = rex_addon::getInstalledAddons();
+
+ rex_install_webservice::deleteCache();
+
+ try {
+ $installer_addons = rex_install_packages::getAddPackages();
+ } catch (rex_functional_exception $e) {
+ $params['message'][] = $e->getMessage();
+ }
+
+ foreach ($rex_addons as $key => $addon) {
+ $params['rex_addons'][$key]['name'] = $addon->getName();
+ $params['rex_addons'][$key]['install'] = $addon->getProperty('install');
+ $params['rex_addons'][$key]['status'] = $addon->getProperty('status');
+ $params['rex_addons'][$key]['version_current'] = $addon->getProperty('version');
+ if (!empty($installer_addons[$key])) {
+ $params['rex_addons'][$key]['version_latest'] = current($installer_addons[$key]["files"])["version"];
+ } else {
+ $params['rex_addons'][$key]['version_latest'] = 0;
+ }
+ }
+
+ # / ADDONS
+
+ # DOMAINS / WEBSITES
+
+ $params['domains'][rex::getServer()]['name'] = rex::getServer();
+ $params['domains'][rex::getServer()]['url'] = rex_getUrl(rex_article::getSiteStartArticleId());
+ $params['domains'][rex::getServer()]['url_404'] = rex_getUrl(rex_article::getNotfoundArticleId());
+
+ if (rex_addon::get('yrewrite')->isAvailable()) {
+
+ $yrewrite_domains = rex_yrewrite::getDomains(true);
+ foreach ($yrewrite_domains as $key => $domain) {
+ $params['domains'][$key]['name'] = $domain->getName();
+ $params['domains'][$key]['url'] = $domain->getUrl();
+ $params['domains'][$key]['url_404'] = rex_yrewrite::getFullUrlByArticleId($domain->getNotfoundId());
+ }
+ }
+
+ # / DOMAINS / WEBSITES
+
+ # SYSLOG
+
+ if (version_compare(rex::getVersion(), '5.9') >= 0) {
+ $log = new rex_log_file(rex_path::log('system.log'));
+ } else {
+ $log = new rex_log_file(rex_path::coreData('system.log'));
+ }
+
+ $i = 0;
+ foreach (new LimitIterator($log, 0, 30) as $entry) {
+ $data = $entry->getData();
+ $params['syslog'][$i]['timestamp'] = $entry->getTimestamp('%d.%m.%Y %H:%M:%S');
+ $params['syslog'][$i]['syslog_type'] = $data[0];
+ $params['syslog'][$i]['syslog_message'] = $data[1];
+ $params['syslog'][$i]['syslog_file'] = (isset($data[2]) ? $data[2] : '');
+ $params['syslog'][$i]['syslog_line'] = (isset($data[3]) ? $data[3] : '');
+ $i++;
+ }
+
+ # / SYSLOG
+
+
+ # USER
+ $params['user'] = rex_sql::factory()->getArray('SELECT `name`, `login`, `email`, `status`, `admin`, `lasttrydate`, `lastlogin` FROM '.rex::getTablePrefix().'user ORDER BY `admin`, `id`');
+ # / USER
+
+ # TODO: Letzte Artikel
+ $params['article'] = rex_sql::factory()->getArray('SELECT `name`, `updateuser`, `updatedate`, `pid` FROM `'.rex::getTablePrefix().'article` ORDER BY `updatedate` DESC LIMIT 10');
+ # / Letzte Artikel
+
+ # TODO: Letzte Medien
+ $params['media'] = rex_sql::factory()->getArray('SELECT `filename`, `updateuser`, `updatedate` FROM `'.rex::getTablePrefix().'media` ORDER BY `updatedate` DESC LIMIT 10');
+ # / Letzte Medien
+
+ # Modules
+ $params['module'] = rex_sql::factory()->getArray('SELECT `name`, `updateuser`, `updatedate` FROM `'.rex::getTablePrefix().'module` ORDER BY `name` ASC');
+ # / Modules
+ }
+
+
+
+ } else {
+ $params['pm_version'] = rex_addon::get('project_manager_plus')->getProperty('version');
+ $params['cms'] = "REDAXO";
+ $params['status'] = 0;
+ $params['message'][] = "Falscher API-Schlüssel.";
+ }
+
+ // TODO: EP, um weitere Parameter einzuhängen
+
+ header('Content-Type: application/json; charset=UTF-8');
+ $response = json_encode($params, true);
+ echo $response;
+ exit();
+ }
+}
diff --git a/lib/Api/Server.php b/lib/Api/Server.php
new file mode 100644
index 0000000..67c3488
--- /dev/null
+++ b/lib/Api/Server.php
@@ -0,0 +1,167 @@
+ true,
+ CURLOPT_AUTOREFERER => true,
+ CURLOPT_MAXREDIRS => 5,
+ CURLOPT_HEADER => false,
+ CURLOPT_SSL_VERIFYPEER => false,
+ CURLOPT_SSL_VERIFYHOST => false,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0',
+ CURLOPT_TIMEOUT => 5,
+ CURLOPT_URL => $url
+ ));
+ $resp = curl_exec($curl);
+
+ $json = json_decode($resp, true);
+
+ if (json_last_error() === JSON_ERROR_NONE && $json !== null) {
+ if ($json['delLog'] == 1) {
+ $params['delLog'] = 1;
+ }
+ } else {
+ $params['delLog'] = -1;
+ }
+
+ // reload data
+ $url = $protocol.urlencode($domain)."/index.php?rex-api-call=project_manager_plus&api_key=".$api_key.'&t='.$timestamp.$param;
+ $curl = curl_init();
+ curl_setopt_array($curl, array(
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_AUTOREFERER => true,
+ CURLOPT_MAXREDIRS => 5,
+ CURLOPT_HEADER => false,
+ CURLOPT_SSL_VERIFYPEER => false,
+ CURLOPT_SSL_VERIFYHOST => false,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0',
+ CURLOPT_TIMEOUT => 5,
+ CURLOPT_URL => $url
+ ));
+
+ $response = curl_exec($curl);
+ $resp = $response;
+ $json = json_decode($resp, true);
+
+ $project_manager_plus_domain = rex_sql::factory()->setDebug(0)->getArray('SELECT * FROM ' . rex::getTable('project_manager_plus_domain') . ' WHERE domain = ? LIMIT 1', [$domain]);
+
+ if (json_last_error() === JSON_ERROR_NONE && $json !== null) {
+
+ if ($json['status'] == 1) {
+
+ rex_sql::factory()->setDebug(0)->setQuery('INSERT INTO ' . rex::getTable('project_manager_plus_logs') . ' (`domain_id`, `createdate`, `raw`) VALUES(?,NOW(),?)', [$project_manager_plus_domain[0]['id'], $resp]);
+ // SET STATUS
+ rex_sql::factory()->setDebug(0)->setQuery("UPDATE " . rex::getTable('project_manager_plus_domain') . " SET status = ?, updatedate = NOW() WHERE id = ?", [1, $project_manager_plus_domain[0]['id']]);
+
+ } else {
+ // SET STATUS
+ rex_sql::factory()->setDebug(0)->setQuery("UPDATE " . rex::getTable('project_manager_plus_domain') . " SET status = ?, updatedate = NOW()WHERE id = ?", [0, $project_manager_plus_domain[0]['id']]);
+ }
+
+ } else {
+ // SET STATUS
+ rex_sql::factory()->setDebug(0)->setQuery("UPDATE " . rex::getTable('project_manager_plus_domain') . " SET status = ?, updatedate = NOW() WHERE id = ?", [-1, $project_manager_plus_domain[0]['id']]);
+ }
+ rex_sql::factory()->setDebug(0)->setQuery("UPDATE " . rex::getTable('project_manager_plus_domain') . " SET updatedate = NOW() WHERE id = ?", [$project_manager_plus_domain[0]['id']]);
+
+ }
+
+ if ($func == "updateData") {
+
+ // reload data
+ $url = $protocol.urlencode($domain)."/index.php?rex-api-call=project_manager_plus&api_key=".$api_key.'&t='.$timestamp.$param;
+ $curl = curl_init();
+ curl_setopt_array($curl, array(
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_AUTOREFERER => true,
+ CURLOPT_MAXREDIRS => 5,
+ CURLOPT_HEADER => false,
+ CURLOPT_SSL_VERIFYPEER => false,
+ CURLOPT_SSL_VERIFYHOST => false,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_TIMEOUT => 5,
+ CURLOPT_URL => $url
+ ));
+
+ $response = curl_exec($curl);
+ $resp = $response;
+ $json = json_decode($resp, true);
+ $json_result = json_encode($json);
+
+ Logger::deleteFile($domain);
+ Logger::init($domain);
+ Logger::log($domain . ' Abruf gestartet', 'Project Manager Server');
+ Logger::log($json_result . ' -> Response', 'Project Manager Server');
+
+ $project_manager_plus_domain = rex_sql::factory()->setDebug(0)->getArray('SELECT * FROM ' . rex::getTable('project_manager_plus_domain') . ' WHERE domain = ? LIMIT 1', [$domain]);
+
+ if (json_last_error() === JSON_ERROR_NONE && $json !== null) {
+
+ if ($json['status'] == 1) {
+
+ rex_sql::factory()->setDebug(0)->setQuery('INSERT INTO ' . rex::getTable('project_manager_plus_logs') . ' (`domain_id`, `createdate`, `raw`) VALUES(?,NOW(),?)', [$project_manager_plus_domain[0]['id'], $resp]);
+ // SET STATUS
+ rex_sql::factory()->setDebug(0)->setQuery("UPDATE " . rex::getTable('project_manager_plus_domain') . " SET status = ?, updatedate = NOW() WHERE id = ?", [1, $project_manager_plus_domain[0]['id']]);
+
+ //WRITE LOGFILE
+ Logger::log('Status 1', 'Project Manager Server');
+
+ } else {
+ // SET STATUS
+ rex_sql::factory()->setDebug(0)->setQuery("UPDATE " . rex::getTable('project_manager_plus_domain') . " SET status = ?, updatedate = NOW()WHERE id = ?", [0, $project_manager_plus_domain[0]['id']]);
+
+ // WRITE LOGFILE
+ Logger::log('Status 0', 'Project Manager Server');
+ }
+
+ } else {
+ // SET STATUS
+ rex_sql::factory()->setDebug(0)->setQuery("UPDATE " . rex::getTable('project_manager_plus_domain') . " SET status = ?, updatedate = NOW() WHERE id = ?", [-1, $project_manager_plus_domain[0]['id']]);
+
+ //WRITE LOGFILE
+ Logger::log('Status -1', 'Project Manager Server');
+ }
+ rex_sql::factory()->setDebug(0)->setQuery("UPDATE " . rex::getTable('project_manager_plus_domain') . " SET updatedate = NOW() WHERE id = ?", [$project_manager_plus_domain[0]['id']]);
+
+ }
+
+ header('Content-Type: application/json; charset=UTF-8');
+ $response = json_encode($params, true);
+ echo $response;
+ exit();
+
+ }
+}
diff --git a/lib/Cronjob/Client.php b/lib/Cronjob/Client.php
new file mode 100644
index 0000000..9d96a16
--- /dev/null
+++ b/lib/Cronjob/Client.php
@@ -0,0 +1,141 @@
+setDebug(0)->getArray('SELECT * FROM ' . rex::getTable('project_manager_plus_domain') . ' ORDER BY updatedate asc');
+
+ /* Addon-Abruf */
+ $multi_curl = curl_multi_init();
+ $resps = array();
+ $options = array(
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_AUTOREFERER => true,
+ CURLOPT_MAXREDIRS => 5,
+ CURLOPT_HEADER => false,
+ CURLOPT_SSL_VERIFYPEER => true,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0',
+ CURLOPT_TIMEOUT => 5 // seconds
+ );
+ foreach ($websites as $website) {
+
+ $domain = $website['domain'];
+ $cms = $website['cms'];
+ $ssl = $website['is_ssl'];
+ $param = $website['param'];
+ $param = explode(',', $param);
+ $param = '&'.implode('&', $param);
+ $protocol = ($ssl == 1) ? "https://" : "http://";
+
+ $timestamp = time();
+
+ $url = $protocol.urlencode($domain)."/index.php?rex-api-call=project_manager_plus&api_key=".$website['api_key'].'&t='.$timestamp.$param;
+
+ if ($cms == 5) {
+ $url = $protocol.urlencode($domain)."/index.php?rex-api-call=project_manager_plus&api_key=".$website['api_key'].'&t='.$timestamp.$param;
+ }
+
+ $resps[$domain] = curl_init($url);
+ curl_setopt_array($resps[$domain], $options);
+ curl_multi_add_handle($multi_curl, $resps[$domain]);
+
+ }
+
+ $active = null;
+
+ do {
+ $mrc = curl_multi_exec($multi_curl, $active);
+ } while ($mrc == CURLM_CALL_MULTI_PERFORM);
+
+ while ($active && $mrc == CURLM_OK) {
+ if (curl_multi_select($multi_curl) != -1) {
+ do {
+ $mrc = curl_multi_exec($multi_curl, $active);
+ } while ($mrc == CURLM_CALL_MULTI_PERFORM);
+ }
+ }
+
+
+
+ foreach ($resps as $domain => $response) {
+
+ $resp = curl_multi_getcontent($response);
+ curl_multi_remove_handle($multi_curl, $response);
+
+ $json = json_decode($resp, true);
+ $json_result = json_encode($json);
+
+ Logger::deleteFile($domain);
+ Logger::init($domain);
+ Logger::log($domain . ' Abruf gestartet', 'Project Manager Server');
+ Logger::log($json_result . ' -> Response', 'Project Manager Server');
+
+ $project_manager_plus_domain = rex_sql::factory()->setDebug(0)->getArray('SELECT * FROM ' . rex::getTable('project_manager_plus_domain') . ' WHERE domain = ? LIMIT 1', [$domain]);
+
+ if (json_last_error() === JSON_ERROR_NONE && $json !== null) {
+
+ if ($json['status'] == 1) {
+
+ rex_sql::factory()->setDebug(0)->setQuery('DELETE FROM ' . rex::getTable('project_manager_plus_logs') . ' WHERE domain_id = ?', [$project_manager_plus_domain[0]['id']]);
+
+ rex_sql::factory()->setDebug(0)->setQuery('INSERT INTO ' . rex::getTable('project_manager_plus_logs') . ' (`domain_id`, `createdate`, `raw`) VALUES(?,NOW(),?)', [$project_manager_plus_domain[0]['id'], $resp]);
+ // SET STATUS
+ rex_sql::factory()->setDebug(0)->setQuery("UPDATE " . rex::getTable('project_manager_plus_domain') . " SET status = ?, updatedate = NOW() WHERE id = ?", [1, $project_manager_plus_domain[0]['id']]);
+
+ //WRITE LOGFILE
+ Logger::log('Status 1', 'Project Manager Server');
+
+
+ } else {
+ // SET STATUS
+ rex_sql::factory()->setDebug(0)->setQuery("UPDATE " . rex::getTable('project_manager_plus_domain') . " SET status = ?, updatedate = NOW()WHERE id = ?", [0, $project_manager_plus_domain[0]['id']]);
+
+ // WRITE LOGFILE
+ Logger::log('Status 0', 'Project Manager Server');
+
+ }
+
+ } else {
+
+ // SET STATUS
+ rex_sql::factory()->setDebug(0)->setQuery("UPDATE " . rex::getTable('project_manager_plus_domain') . " SET status = ?, updatedate = NOW() WHERE id = ?", [-1, $project_manager_plus_domain[0]['id']]);
+
+ //WRITE LOGFILE
+ Logger::log('Status -1', 'Project Manager Server');
+
+
+ }
+
+ rex_sql::factory()->setDebug(0)->setQuery("UPDATE " . rex::getTable('project_manager_plus_domain') . " SET updatedate = NOW() WHERE id = ?", [$project_manager_plus_domain[0]['id']]);
+
+ //WRITE LOGFILE
+
+
+ }
+
+ curl_multi_close($multi_curl);
+
+ return true;
+
+ }
+ public function getTypeName()
+ {
+ return rex_i18n::msg('project_manager_plus_cronjob_data_name');
+ }
+
+ public function getParamFields()
+ {
+ return [];
+ }
+}
diff --git a/lib/Cronjob/Favicon.php b/lib/Cronjob/Favicon.php
new file mode 100644
index 0000000..b89522c
--- /dev/null
+++ b/lib/Cronjob/Favicon.php
@@ -0,0 +1,187 @@
+setDebug(0)->getArray("SELECT * FROM " . rex::getTable('project_manager_plus_domain') . " ORDER BY updatedate asc ");
+ $multi_curl = curl_multi_init();
+ $ch = [];
+
+ foreach ($domains as $domain) {
+
+ $ssl = $domain['is_ssl'];
+ $protocol = ($ssl == 1) ? "https://" : "http://";
+ $ch[$domain['domain']] = curl_init();
+ $fp[$domain['domain']] = fopen(rex_path::pluginAssets('project_manager_plus', 'server', 'favicon/'.$domain['domain'].'.png'), 'w+');
+ //curl_setopt($ch[$domain['domain']], CURLOPT_URL, "https://www.google.com/s2/u/0/favicons?domain=".$domain['domain']."&sz=64");
+
+ $faviconUrl = self::getFavicon($protocol.$domain['domain']);
+
+ if (is_array($faviconUrl)) {
+ $favicon = $faviconUrl[0];
+ } else {
+ $favicon = $faviconUrl;
+ }
+
+ if ($favicon == 'FALSE') {
+ $favicon = rex::getServer().'/assets/addons/project_manager_plus/plugins/server/favicon/redaxo-favicon.png';
+ }
+
+ curl_setopt($ch[$domain['domain']], CURLOPT_URL, $favicon);
+
+ curl_setopt($ch[$domain['domain']], CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($ch[$domain['domain']], CURLOPT_HEADER, 0);
+ curl_setopt($ch[$domain['domain']], CURLOPT_FILE, $fp[$domain['domain']]);
+ curl_multi_add_handle($multi_curl, $ch[$domain['domain']]);
+
+ }
+ $active = null;
+ do {
+ curl_multi_exec($multi_curl, $active);
+ } while ($active > 0);
+
+ foreach ($domains as $domain) {
+ curl_multi_remove_handle($multi_curl, $ch[$domain['domain']]);
+ fwrite($fp[$domain['domain']], "");
+ fclose($fp[$domain['domain']]);
+ }
+
+ curl_multi_close($multi_curl);
+
+ return true;
+
+ }
+ public function getTypeName()
+ {
+ return rex_i18n::msg('project_manager_plus_cronjob_favicon_name');
+ }
+
+ public function getParamFields()
+ {
+ return [];
+ }
+
+ public function getFavicon($url)
+ {
+
+ $file_headers = @get_headers($url);
+ $found = false;
+ // 1. CHECK THE DOM FOR THE TAG
+ // check if the url exists - if the header returned is not 404
+ if ($file_headers[0] != 'HTTP/1.1 404 Not Found') {
+ $dom = new \DOMDocument();
+ $dom->strictErrorChecking = false;
+ @$dom->loadHTMLfile($url); //@ to discard all the warnings of malformed htmls
+ if (!$dom) {
+ // $error[]='Error parsing the DOM of the file';
+ } else {
+
+ if (!is_null($dom->baseURI)) {
+ $domxml = simplexml_import_dom($dom);
+ }
+
+ if ($domxml) {
+
+ //check for the historical rel="shortcut icon"
+ if ($domxml->xpath('//link[@rel="shortcut icon"]')) {
+ $path = $domxml->xpath('//link[@rel="shortcut icon"]');
+ $faviconURL = $path[0]['href'];
+ # check if absolute url or relative path
+ $favicon_elems = parse_url($faviconURL);
+ # if relative
+ if (!isset($favicon_elems['host'])) {
+ $faviconURL = $url . $faviconURL;
+ }
+
+ $favicon_headers = @get_headers($faviconURL);
+ if (is_array($favicon_headers)) {
+ if (!in_array('HTTP/1.1 404 Not Found', $favicon_headers)) {
+ $found == true;
+ return $faviconURL;
+ }
+ }
+
+ //check for the HTML5 rel="icon"
+ } elseif ($domxml->xpath('//link[@rel="icon"]')) {
+ $path = $domxml->xpath('//link[@rel="icon"]');
+ $faviconURL = $path[0]['href'];
+ # check if absolute url or relative path
+ $favicon_elems = parse_url($faviconURL);
+ # if relative
+ if (!isset($favicon_elems['host'])) {
+ $faviconURL = $url . $faviconURL;
+ }
+
+ $favicon_headers = @get_headers($faviconURL);
+ if (is_array($favicon_headers)) {
+ if (!in_array('HTTP/1.1 404 Not Found', $favicon_headers)) {
+ $found == true;
+ return $faviconURL;
+ }
+ }
+
+ } else {
+ //$error[]="The URL does not contain a favicon tag.";
+ }
+
+ if ($found == false) {
+ return 'FALSE';
+ }
+
+ }
+
+
+ }
+
+
+ // 2. CHECK DIRECTLY FOR favicon.ico OR favicon.png FILE
+ // the two seem to be most common
+ if ($found == false) {
+ $parse = parse_url($url);
+ $favicon_headers = @get_headers("http://".$parse['host']."/favicon.ico");
+ if ($favicon_headers[0] != 'HTTP/1.1 404 Not Found') {
+ $faviconURL = "/favicon.ico";
+ $favicon_elems = parse_url($faviconURL);
+ # if relative
+ if (!isset($favicon_elems['host'])) {
+ $faviconURL = $url . $faviconURL;
+ }
+ $found == true;
+ return $faviconURL;
+ }
+ $favicon_headers = @get_headers("http://".$parse['host']."/favicon.png");
+ if ($favicon_headers[0] != 'HTTP/1.1 404 Not Found') {
+ $faviconURL = "/favicon.png";
+ $favicon_elems = parse_url($faviconURL);
+ # if relative
+ if (!isset($favicon_elems['host'])) {
+ $faviconURL = $url . $faviconURL;
+ }
+ $found == true;
+ return $faviconURL;
+ }
+ if ($found == false) {
+ //$error[]= "Files favicon.ico and .png do not exist on the server's root.";
+ }
+ }
+ // if the URL does not exists ...
+ } else {
+ // $error[]="URL does not exist";
+ }
+
+ if ($found == false && isset($error)) {
+ return $error;
+ }
+ }
+}
diff --git a/lib/Cronjob/Hosting.php b/lib/Cronjob/Hosting.php
new file mode 100644
index 0000000..3fd21a7
--- /dev/null
+++ b/lib/Cronjob/Hosting.php
@@ -0,0 +1,138 @@
+setDebug(0)->getArray('SELECT D.domain AS domain, D.is_ssl as is_ssl FROM
+ (SELECT domain, createdate FROM rex_project_manager_plus_domain_hosting) AS H
+ RIGHT JOIN
+ (SELECT domain, updatedate, is_ssl FROM rex_project_manager_plus_domain) AS D
+ ON
+ H.domain = D.domain
+ GROUP BY D.domain
+ ORDER BY H.createdate ASC');
+
+
+ $message = '';
+ $error = false;
+
+ foreach ($websites as $website) {
+
+ // because call limit ip-api.com
+ usleep(800000);
+ $domain = $website['domain'];
+ $ip = gethostbyname(idn_to_ascii($domain, INTL_IDNA_VARIANT_UTS46));
+ $url = 'http://ip-api.com/json/'.$ip;
+
+ $ch = curl_init();
+
+ $options = array(
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_AUTOREFERER => true,
+ CURLOPT_MAXREDIRS => 4,
+ CURLOPT_HEADER => false,
+ CURLOPT_SSL_VERIFYPEER => false,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_TIMEOUT => 10,
+ CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0',
+ CURLOPT_URL => $url
+ );
+
+ curl_setopt_array($ch, $options);
+ $resps[$domain .";hosting"] = curl_exec($ch);
+
+ curl_close($ch);
+
+ if ($website['is_ssl']) {
+ $prefix = "https://";
+
+ // SSL Certificate
+ set_error_handler(function () {return true;});
+ $orignal_parse = parse_url($prefix.$domain, PHP_URL_HOST);
+ $get = stream_context_create(array("ssl" => array("capture_peer_cert" => true)));
+ $read = stream_socket_client("ssl://".$orignal_parse.":443", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $get);
+ $cert = stream_context_get_params($read);
+ restore_error_handler();
+ $certinfo = openssl_x509_parse($cert['options']['ssl']['peer_certificate']);
+
+ $arr = json_decode($resps[$domain .";hosting"], true);
+ $arr['validFrom'] = $certinfo['validFrom_time_t'];
+ $arr['validTo'] = $certinfo['validTo_time_t'];
+ $resps[$domain .";hosting"] = json_encode($arr);
+
+ } else {
+
+ $arr = json_decode($resps[$domain .";hosting"], true);
+ $arr['validFrom'] = "-";
+ $arr['validTo'] = "-";
+ $resps[$domain .";hosting"] = json_encode($arr);
+
+ }
+
+ }
+
+ foreach ($resps as $key => $response) {
+
+ $domain = explode(";", $key)[0];
+ $mode = explode(";", $key)[1];
+
+ $hosting = json_decode($response, true);
+ $ip = '';
+ $ip = gethostbyname(idn_to_ascii($domain));
+
+ if (json_last_error() === JSON_ERROR_NONE && (!array_key_exists("message", $hosting))) {
+ if ($mode == "hosting") {
+
+ rex_sql::factory()->setDebug(0)->setQuery('INSERT INTO ' . rex::getTable('project_manager_plus_domain_hosting') . ' (`domain`, `raw`, `createdate`, `ip`, `status`) VALUES(:domain, :response, NOW(), :ip, 1)
+ ON DUPLICATE KEY UPDATE domain = :domain, `raw` = :response, createdate = NOW(), `ip` = :ip, `status` = 1', [":domain" => $domain, ":response" => $response, ":ip" => $ip]);
+
+ }
+ } else {
+
+ // ERROR HANDLE
+ if ($mode == "hosting") {
+
+ rex_sql::factory()->setDebug(0)->setQuery('INSERT INTO ' . rex::getTable('project_manager_plus_domain_hosting') . ' (`domain`, `raw`, `createdate`, `ip`, `status`) VALUES(:domain, :response, NOW(), :ip, -1)
+ ON DUPLICATE KEY UPDATE domain = :domain, `raw` = :response, createdate = NOW(), `ip` = :ip, `status` = -1', [":domain" => $domain, ":response" => $response, ":ip" => $ip]);
+
+ }
+
+ $message .= $domain.': '.$hosting['status'].' '.$hosting['message'].'\n';
+ $error = true;
+
+ }
+ }
+
+
+
+
+ if ($error === true) {
+ $this->setMessage($message);
+ return false;
+ } else {
+ return true;
+ }
+
+ return true;
+ }
+
+ public function getTypeName()
+ {
+ return rex_i18n::msg('project_manager_plus_cronjob_hosting_name');
+ }
+
+ public function getParamFields()
+ {
+ return [];
+ }
+}
diff --git a/lib/Cronjob/PageSpeed.php b/lib/Cronjob/PageSpeed.php
new file mode 100644
index 0000000..a8fa958
--- /dev/null
+++ b/lib/Cronjob/PageSpeed.php
@@ -0,0 +1,148 @@
+setDebug(0)->getArray('SELECT count(*) as count FROM rex_project_manager_plus_domain');
+ if ($count[0]['count'] <= 10) {
+ $count = 1;
+ } else {
+ $count = $count[0]['count'] / 10;
+ $count = round($count, 0, PHP_ROUND_HALF_UP);
+ }
+
+ for ($i = 0; $i < $count; $i++) {
+ $this->getData();
+ }
+
+ return true;
+
+ }
+
+ public function getData()
+ {
+
+ $websites = rex_sql::factory()->setDebug(0)->getArray('SELECT D.domain AS domain, D.is_ssl as is_ssl FROM
+ (SELECT domain, createdate FROM rex_project_manager_plus_domain_psi) AS PSI
+ RIGHT JOIN
+ (SELECT domain, updatedate, is_ssl FROM rex_project_manager_plus_domain) AS D
+ ON
+ PSI.domain = D.domain
+ GROUP BY D.domain
+ ORDER BY PSI.createdate ASC LIMIT 10');
+
+ $error = false;
+ $multi_curl = curl_multi_init();
+ $resps = array();
+ $options = array(
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_AUTOREFERER => true,
+ CURLOPT_MAXREDIRS => 4,
+ CURLOPT_HEADER => false,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_SSL_VERIFYPEER => false,
+ CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0',
+ CURLOPT_TIMEOUT => 30 // seconds
+ );
+
+ foreach ($websites as $website) {
+
+ $fstreams = array();
+
+ $domain = $website['domain'];
+ if ($website['is_ssl']) {
+ $prefix = "https://";
+ } else {
+ $prefix = "http://";
+ }
+
+ $url_desktop = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed?filter_third_party_resources=false&locale=de_DE&screenshot=true&snapshots=false&strategy=desktop&key='.rex_config::get('project_manager_plus/pagespeed', 'project_manager_plus_pagespeed_api_key').'&url='.urlencode($prefix.$website['domain']);
+ $url_mobile = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed?filter_third_party_resources=false&locale=de_DE&screenshot=true&snapshots=false&strategy=mobile&key='.rex_config::get('project_manager_plus/pagespeed', 'project_manager_plus_pagespeed_api_key').'&url='.urlencode($prefix.$website['domain']);
+ $resps[$domain.";mobile"] = curl_init($url_mobile);
+ $resps[$domain.";desktop"] = curl_init($url_desktop);
+ curl_setopt_array($resps[$domain.";mobile"], $options);
+ curl_setopt_array($resps[$domain.";desktop"], $options);
+ curl_multi_add_handle($multi_curl, $resps[$domain.";mobile"]);
+ curl_multi_add_handle($multi_curl, $resps[$domain.";desktop"]);
+
+ }
+
+ $active = null;
+ do {
+ curl_multi_exec($multi_curl, $active);
+ } while ($active > 0);
+
+
+ foreach ($resps as $key => $response) {
+ $domain = explode(";", $key)[0];
+ $mode = explode(";", $key)[1];
+ $resp = curl_multi_getcontent($response);
+ curl_multi_remove_handle($multi_curl, $response);
+ $pagespeed = json_decode($resp, true);
+
+ $score_mobile = 0;
+ $score_desktop = 0;
+ if (isset($pagespeed['lighthouseResult'])) {
+ if ($pagespeed['lighthouseResult']['categories']['performance']['score'] != null) {
+ $score_mobile = $pagespeed['lighthouseResult']['categories']['performance']['score'];
+ }
+ if ($pagespeed['lighthouseResult']['categories']['performance']['score'] != null) {
+ $score_desktop = $pagespeed['lighthouseResult']['categories']['performance']['score'];
+ }
+ }
+ if (json_last_error() === JSON_ERROR_NONE && (!array_key_exists("error", $pagespeed))) {
+ if ($mode == "mobile") {
+ rex_sql::factory()->setDebug(0)->setQuery('INSERT INTO ' . rex::getTable('project_manager_plus_domain_psi') . ' (`domain`, `raw`, `createdate`, `score_mobile`, `status`) VALUES(:domain, :resp, NOW(), :score_mobile, 1)
+ ON DUPLICATE KEY UPDATE domain = :domain, `raw` = :resp, createdate = NOW(), `score_mobile` = :score_mobile, `status` = 1', [":domain" => $domain, ":resp" => $resp, ":score_mobile" => $score_mobile]);
+ } elseif ($mode == "desktop") {
+ rex_sql::factory()->setDebug(0)->setQuery('INSERT INTO ' . rex::getTable('project_manager_plus_domain_psi') . ' (`domain`, `raw`, `createdate`, `score_desktop`, `status`) VALUES(:domain, :resp, NOW(), :score_desktop, 1)
+ ON DUPLICATE KEY UPDATE domain = :domain, `raw` = :resp, createdate = NOW(), `score_desktop` = :score_desktop, `status` = 1', [":domain" => $domain, ":resp" => $resp, ":score_desktop" => $score_desktop]);
+ }
+ } else {
+
+ // ERROR HANDLE
+ if ($mode == "desktop") {
+
+ rex_sql::factory()->setDebug(0)->setQuery('INSERT INTO ' . rex::getTable('project_manager_plus_domain_psi') . ' (`domain`, `raw`, `createdate`, `status`) VALUES(:domain, :resp, NOW(), -1)
+ ON DUPLICATE KEY UPDATE domain = :domain, `raw` = :resp, createdate = NOW(), `status` = -1', [":domain" => $domain, ":resp" => $resp]);
+
+ } elseif ($mode == "mobile") {
+ rex_sql::factory()->setDebug(0)->setQuery('INSERT INTO ' . rex::getTable('project_manager_plus_domain_psi') . ' (`domain`, `raw`, `createdate`, `status`) VALUES(:domain, :resp, NOW(), -1)
+ ON DUPLICATE KEY UPDATE domain = :domain, `raw` = :resp, createdate = NOW(), `status` = -1', [":domain" => $domain, ":resp" => $resp]);
+
+ }
+
+ $this->setMessage($pagespeed['error']['errors'][0]['message'].': '.$pagespeed['error']['errors'][0]['reason']);
+ $error = true;
+
+ }
+ }
+ curl_multi_close($multi_curl);
+
+ if ($error === true) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+ public function getTypeName()
+ {
+ return rex_i18n::msg('project_manager_plus_cronjob_pagespeed_name');
+ }
+
+ public function getParamFields()
+ {
+ return [];
+ }
+}
diff --git a/lib/Domain.php b/lib/Domain.php
new file mode 100644
index 0000000..67622b3
--- /dev/null
+++ b/lib/Domain.php
@@ -0,0 +1,127 @@
+getDomain();
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ $output = curl_exec($ch);
+ curl_close($ch);
+ $data = json_decode($output, true);
+ return $data;
+ }
+
+ // Funktion zum Abrufen der historischen Verfügbarkeitsdaten von HetrixTools
+ public function getHetrixToolsHistoricalData($apiKey, $monitorId, $startDate, $endDate)
+ {
+ $startDate = date("Y-m-d", strtotime("-1 day"));
+ $endDate = date("Y-m-d");
+ $url = "https://api.hetrixtools.com/v2/$apiKey/uptime/$monitorId/?start_date=$startDate&end_date=$endDate";
+ $response = file_get_contents($url);
+ $data = json_decode($response, true);
+ return $data;
+ }
+
+
+ public function getFavicon()
+ {
+ $protocol = ($this->isSsl() == 1) ? "https://" : "http://";
+ $faviconUrl = self::getFavicon($protocol . $this->getDomain());
+ if (is_array($faviconUrl)) {
+ $favicon = $faviconUrl[0];
+ } else {
+ $favicon = $faviconUrl;
+ }
+ if ($favicon == 'FALSE') {
+ $favicon = \rex::getServer() . '/assets/addons/project_manager_plus/favicon/redaxo-favicon.png';
+ }
+ return $favicon;
+ }
+
+ /** QualySSL Labs Score */
+ public function getQualysSslLabsScore()
+ {
+ $url = 'https://www.ssllabs.com/ssltest/analyze.html?d=' . $this->getDomain();
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ $output = curl_exec($ch);
+ curl_close($ch);
+ $data = json_decode($output, true);
+ return $data;
+ }
+
+ /** Mozilla Observer Score */
+ public function getMozillaObserverScore()
+ {
+ $url = 'https://observatory.mozilla.org/analyze/' . $this->getDomain();
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ $output = curl_exec($ch);
+ curl_close($ch);
+ $data = json_decode($output, true);
+ return $data;
+ }
+
+ public function getIp()
+ {
+ return gethostbyname(idn_to_ascii($this->getDomain(), INTL_IDNA_VARIANT_UTS46));
+ }
+
+ /* PageSpeed Score and PageSpeed Insights (all) */
+ public function getPageSpeedScore()
+ {
+ $url = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=' . $this->getDomain();
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ $output = curl_exec($ch);
+ curl_close($ch);
+ $data = json_decode($output, true);
+ return $data;
+ }
+
+ // Funktion zum Abrufen der SecurityHeaders Bewertung
+ public function getSecurityHeadersScore($domain)
+ {
+ $url = "https://securityheaders.com/?q=$domain&followRedirects=on";
+ $response = file_get_contents($url . '&hide=on');
+ preg_match('/Grade: ([A-F])/', $response, $matches);
+ return $matches[1] ?? 'N/A';
+ }
+
+ /** Lighthouse-Kennzahlen für Mobil/Desktop SEO/Barrierefreiheit/Leistung/Best Practices abrufen */
+ public function getLighthouseMetrics()
+ {
+ $url = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=' . $this->getDomain();
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ $output = curl_exec($ch);
+ curl_close($ch);
+ $data = json_decode($output, true);
+ return $data;
+ }
+
+
+ public function getDomain()
+ {
+ return $this->getValue('domain');
+ }
+
+ public function isSsl()
+ {
+ return $this->getValue('is_ssl');
+ }
+}
diff --git a/lib/Logger.php b/lib/Logger.php
new file mode 100644
index 0000000..9f0f25a
--- /dev/null
+++ b/lib/Logger.php
@@ -0,0 +1,47 @@
+add($data);
+ }
+
+ public static function getPath($domain)
+ {
+ return rex_path::log('project_manager_plus_'.$domain.'_last.log');
+ }
+
+ public static function deleteFile($domain)
+ {
+ rex_file::delete(rex_path::log('project_manager_plus_'.$domain.'_last.log'));
+ ;
+ }
+
+ public static function close()
+ {
+ self::$logfile = null;
+ self::$init = false;
+ }
+}
diff --git a/package.yml b/package.yml
index 7bf3242..c4ad554 100644
--- a/package.yml
+++ b/package.yml
@@ -1,35 +1,84 @@
-package: project_manager
-version: '1.5.6'
-author: 'Friends Of REDAXO'
-supportpage: https://github.com/FriendsOfREDAXO/project_manager
+package: project_manager_plus
+version: '2.0.0-dev'
+author: 'Friends Of REDAXO, Alexander Walther'
+supportpage: https://github.com/alexplusde/project_manager_plus
-# Seiten
page:
- title: Projekt Manager
- perm: project_manager[]
+ title: Projekt Manager Plus
+ perm: admin
icon: rex-icon fa-handshake-o
- # Unterseiten
subpages:
main:
- title: 'translate:project_manager_main'
- perm: project_manager[]
+ title: 'translate:project_manager_plus_main'
+ perm: admin
icon: rex-icon fa-info
itemclass: pull-right
-
-plugins:
- - server
- - client
- - pagespeed
- - hosting
+ client:
+ title: 'translate:project_manager_plus_client'
+ perm: admin
+ icon: rex-icon fa-wrench
+ server_overview:
+ title: 'translate:project_manager_plus_server_overview'
+ perm: admin
+ icon: rex-icon fa-wrench
+ server_projects:
+ title: 'translate:project_manager_plus_server_project_detail'
+ perm: admin
+ icon: rex-icon fa-wrench
+ server_config:
+ title: 'translate:project_manager_plus_server_config'
+ perm: admin
+ icon: rex-icon fa-wrench
+ hosting:
+ title: translate:project_manager_plus_hosting_title
+ pagespeed_overview:
+ title: 'translate:project_manager_plus_pagespeed_title'
+ pagespeed_config:
+ title: 'translate:project_manager_plus_pagespeed_config'
-# Abhängigkeiten
-# Anforderungen ans System oder anderere AddOns, um dieses AddOn installieren oder update zu können
requires:
- redaxo: '^5.2' # benötigt mindestens REDAXO 5.2
+ packages:
+ cronjob: '>=2.3.0'
+ project_manager_plus: '^1.5.0'
+ yform: '>=3.4.2'
+ redaxo: '^5.15'
php:
- version: '>=7.0' # benötigt mindestens PHP 7
+ version: '>=8.0'
-# Plugins die automatisch installiert werden sollen
-#system_plugins:
- #- client
+redaxo_versions:
+ ['5.12.0', '5.12.1', '5.13.0', '5.13.1', '5.13.2', '5.13.3', '5.13.4', '5.14.0', '5.14.1', '5.14.2', '5.15.0', '5.15.1', '5.16.0', '5.16.1', '5.17.0', '5.17.1', '5.18.0', '5.18.1']
+
+php_versions:
+ 7.4.0:
+ releasedate: '2019-11-28'
+ supportenddate: '2021-11-28'
+ securityenddate: '2022-11-28'
+ 8.0.0:
+ releasedate: '2020-11-26'
+ supportenddate: '2022-11-26'
+ securityenddate: '2023-11-26'
+ 8.1.0:
+ releasedate: '2021-11-25'
+ supportenddate: '2023-11-25'
+ securityenddate: '2025-12-31'
+ 8.2.0:
+ releasedate: '2022-12-08'
+ supportenddate: '2024-12-31'
+ securityenddate: '2026-12-31'
+ 8.3.0:
+ releasedate: '2023-11-23'
+ supportenddate: '2025-12-31'
+ securityenddate: '2027-12-31'
+ 8.4.0:
+ releasedate: '2024-11-21'
+ supportenddate: '2026-12-31'
+ securityenddate: '2028-12-31'
+ 9.0.0:
+ releasedate: '2026-11-26'
+ supportenddate: '2028-12-31'
+ securityenddate: '2030-12-31'
+
+default_config:
+ min_redaxo_version: '5.17.0'
+ min_php_version: '8.3'
diff --git a/pages/hosting-content.php b/pages/hosting-content.php
new file mode 100644
index 0000000..917325f
--- /dev/null
+++ b/pages/hosting-content.php
@@ -0,0 +1,50 @@
+setDebug(0)->getArray($query, [$domain]);
+
+ if (count($result) > 0) {
+
+ $item = $result[0];
+ $raw = json_decode($item['raw'], true);
+
+ if (is_array($raw)) {
+
+ if (is_numeric($raw['validTo'])) {
+
+ if ($raw['validTo'] < (time() + 2764800)) {
+ $validTo = ''.rex_formatter::format($raw['validTo'], 'date', 'd.m.Y H:i:s').'';
+ $validFrom = rex_formatter::format($raw['validFrom'], 'date', 'd.m.Y H:i:s');
+ } elseif ($raw['validTo'] < time()) {
+ $validTo = ''.rex_formatter::format($raw['validTo'], 'date', 'd.m.Y H:i:s').'';
+ $validFrom = rex_formatter::format($raw['validFrom'], 'date', 'd.m.Y H:i:s');
+ } else {
+ $validTo = rex_formatter::format($raw['validTo'], 'date', 'd.m.Y H:i:s');
+ $validFrom = rex_formatter::format($raw['validFrom'], 'date', 'd.m.Y H:i:s');
+ }
+ } else {
+ $validFrom = "-";
+ $validTo = "-";
+ }
+
+ $output = ''.$this->i18n('organisation').' | '.$this->i18n('isp').' | '. $this->i18n('project_manager_plus_hosting_ip').' | '.$this->i18n('validFrom').' | '.$this->i18n('validTo').' |
---|---|---|---|---|
'.(isset($raw['org']) ? $raw['org'] : '').' | '.(isset($raw['isp']) ? $raw['isp'] : '').' '.(isset($raw['zip']) ? $raw['zip'] : '').' '.(isset($raw['city']) ? $raw['city'] : '').' '.(isset($raw['country']) ? $raw['country'] : '').' | '.(isset($item['ip']) ? $item['ip']: '').' | '.$validFrom.' | '.$validTo.' |