From 5f65cecda5d802654a3ffead800845636e87c834 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Wed, 27 Feb 2019 09:37:50 +0100 Subject: [PATCH 01/11] handle Greek windows-1253 encoding as iso-8859-7 --- api/src/Translation.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/src/Translation.php b/api/src/Translation.php index 95486f72dc..ab6a9fc1b7 100644 --- a/api/src/Translation.php +++ b/api/src/Translation.php @@ -8,7 +8,6 @@ * Copyright (C) 2000, 2001 Joseph Engo * @license http://opensource.org/licenses/lgpl-license.php LGPL - GNU Lesser General Public License * @package api - * @version $Id$ */ namespace EGroupware\Api; @@ -901,6 +900,9 @@ class Translation case 'windows-1250': $from = 'iso-8859-2'; break; + case 'windows-1253': + $from = 'iso-8859-7'; + break; case 'windows-1257': $from = 'iso-8859-13'; break; From b4d5584fe75554e521ccf8415dd17f11bc3be4ce Mon Sep 17 00:00:00 2001 From: Hadi Nategh Date: Wed, 27 Feb 2019 11:00:53 +0100 Subject: [PATCH 02/11] Make editableWidget to set height when in edit mode --- api/js/etemplate/et2_core_editableWidget.js | 5 +++++ api/js/etemplate/et2_widget_htmlarea.js | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/api/js/etemplate/et2_core_editableWidget.js b/api/js/etemplate/et2_core_editableWidget.js index ddc8d27e72..7d0a2c386b 100644 --- a/api/js/etemplate/et2_core_editableWidget.js +++ b/api/js/etemplate/et2_core_editableWidget.js @@ -41,6 +41,11 @@ var et2_editableWidget = (function(){ "use strict"; return et2_inputWidget.exten type: "string", default: et2_no_init, description: "Additional parameters passed to save_callback" + }, + editable_height: { + name: "Editable height", + description: "Set height for widget while in edit mode", + type: "string" } }, diff --git a/api/js/etemplate/et2_widget_htmlarea.js b/api/js/etemplate/et2_widget_htmlarea.js index 80454c20fb..2320b643da 100644 --- a/api/js/etemplate/et2_widget_htmlarea.js +++ b/api/js/etemplate/et2_widget_htmlarea.js @@ -22,18 +22,18 @@ var et2_htmlarea = (function(){ "use strict"; return et2_editableWidget.extend([et2_IResizeable], { attributes: { - 'mode': { + mode: { 'name': 'Mode', 'description': 'One of {ascii|simple|extended|advanced}', 'default': '', 'type': 'string' }, - 'height': { + height: { 'name': 'Height', 'default': et2_no_init, 'type': 'string' }, - 'width': { + width: { 'name': 'Width', 'default': et2_no_init, 'type': 'string' @@ -214,7 +214,7 @@ var et2_htmlarea = (function(){ "use strict"; return et2_editableWidget.extend([ this.options.readonly = _value; if(this.options.readonly) { - this.editor.remove(); + if (this. editor) this.editor.remove(); this.htmlNode = jQuery(document.createElement(this.options.readonly ? "div" : "textarea")) .css('height', this.options.height) .addClass('et2_textbox_ro'); @@ -227,7 +227,7 @@ var et2_htmlarea = (function(){ "use strict"; return et2_editableWidget.extend([ if(!this.editor) { this.htmlNode = jQuery(document.createElement("textarea")) - .css('height', this.options.height) + .css('height', (this.options.editable_height ? this.options.editable_height : this.options.height)) .val(value); this.setDOMNode(this.htmlNode[0]); this.init_editor(); From d44cffbf8bf793408d15972faee202186b2e752f Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Wed, 27 Feb 2019 11:59:05 +0100 Subject: [PATCH 03/11] new admin-cli.php --delete-user parameter --not-existing to delete all no longer existing accounts --- admin/admin-cli.php | 5 +- .../class.admin_cmd_change_account_id.inc.php | 8 +- admin/inc/class.admin_cmd_check_acl.inc.php | 6 +- .../class.admin_cmd_delete_account.inc.php | 166 +++++++++++++++--- 4 files changed, 155 insertions(+), 30 deletions(-) diff --git a/admin/admin-cli.php b/admin/admin-cli.php index 1ac967cd69..37e7e0a5f3 100755 --- a/admin/admin-cli.php +++ b/admin/admin-cli.php @@ -152,6 +152,7 @@ function run_command(admin_cmd $cmd) break; case '--try-run': // only run checks + case '--dry-run': // only run checks $dry_run = true; break; @@ -177,7 +178,8 @@ function run_command(admin_cmd $cmd) } //_debug_array($cmd); try { - print_r($cmd->run($time, true, $skip_checks, $dry_run)); + $msg = $cmd->run($time, true, $skip_checks, $dry_run); + if (!is_bool($msg) && $msg) print_r($msg); // cli can NOT clear instance cache of APC(u), as cli uses different shared memory then webserver // --> we use a webservice call to clear cache (might fail if no domain in specified in webserver_url or on command line) @@ -327,6 +329,7 @@ function usage($action=null,$ret=0) echo " Change/set the password for a given user\n"; echo "--delete-user admin-account[@domain],admin-password,account-to-delete[,account-to-move-data]\n"; echo " Deletes a user from EGroupware. It's data can be moved to an other user or it get deleted too.\n"; + echo " You can use '--not-existing' for accounts-to-delete, to delete all no (longer) existing users and groups.\n"; echo "--edit-group admin-account[@domain],admin-password,group[=new-group-name],email[,members,...]\n"; echo " Edit or add a group to EGroupware. If you specify members, they *replace* the exiting members!\n"; echo "--delete-group admin-account[@domain],admin-password,group-to-delete\n"; diff --git a/admin/inc/class.admin_cmd_change_account_id.inc.php b/admin/inc/class.admin_cmd_change_account_id.inc.php index 39b6549523..2306867a95 100644 --- a/admin/inc/class.admin_cmd_change_account_id.inc.php +++ b/admin/inc/class.admin_cmd_change_account_id.inc.php @@ -5,7 +5,7 @@ * @link http://www.egroupware.org * @author Ralf Becker * @package admin - * @copyright (c) 2007-18 by Ralf Becker + * @copyright (c) 2007-19 by Ralf Becker * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License */ @@ -37,13 +37,13 @@ class admin_cmd_change_account_id extends admin_cmd } /** - * Query changes from all apps + * Query account columns from all apps * * Apps mark columns containing account-ids in "meta" attribute as (account|user|group)[-(abs|commasep|serialized)] * * @return array appname => array( table => array(column(s))) */ - private function get_changes() + public static function get_account_colums() { // happens if one used "root_admin" and config-password if (empty($GLOBALS['egw_info']['apps'])) @@ -145,7 +145,7 @@ class admin_cmd_change_account_id extends admin_cmd { throw new Api\Exception\WrongUserinput(implode("\n", $errors), 16); } - $columns2change = $this->get_changes(); + $columns2change = self::get_account_colums(); $total = 0; foreach($columns2change as $app => $data) { diff --git a/admin/inc/class.admin_cmd_check_acl.inc.php b/admin/inc/class.admin_cmd_check_acl.inc.php index 63d4e5ad21..f4c5a4bcef 100644 --- a/admin/inc/class.admin_cmd_check_acl.inc.php +++ b/admin/inc/class.admin_cmd_check_acl.inc.php @@ -5,9 +5,8 @@ * @link http://www.egroupware.org * @author Ralf Becker * @package admin - * @copyright (c) 2007-16 by Ralf Becker + * @copyright (c) 2007-19 by Ralf Becker * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @version $Id$ */ /** @@ -40,7 +39,8 @@ class admin_cmd_check_acl extends admin_cmd admin_cmd::_instanciate_accounts(); $deleted = 0; - if (($all_accounts = admin_cmd::$accounts->search(array('type'=>'both')))) + // get all accounts: users+groups and also non-active ones (not yet deleted!) + if (($all_accounts = admin_cmd::$accounts->search(array('type'=>'both','active'=>false)))) { $ids = array(); foreach($all_accounts as $account) diff --git a/admin/inc/class.admin_cmd_delete_account.inc.php b/admin/inc/class.admin_cmd_delete_account.inc.php index 5bf54ea56b..7096f2ce16 100644 --- a/admin/inc/class.admin_cmd_delete_account.inc.php +++ b/admin/inc/class.admin_cmd_delete_account.inc.php @@ -5,9 +5,8 @@ * @link http://www.egroupware.org * @author Ralf Becker * @package admin - * @copyright (c) 2007-16 by Ralf Becker + * @copyright (c) 2007-19 by Ralf Becker * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @version $Id$ */ use EGroupware\Api; @@ -21,6 +20,7 @@ class admin_cmd_delete_account extends admin_cmd * Constructor * * @param string|int|array $account account name or id, or array with all parameters + * or string "--not-existing" to delete all, in account repository no longer existing, accounts * @param string $new_user =null if specified, account to transfer the data to (users only) * @param string $is_user =true type of the account: true=user, false=group * @param array $extra =array() values for requested(_email), comment, ... @@ -49,6 +49,13 @@ class admin_cmd_delete_account extends admin_cmd */ protected function exec($check_only=false) { + // check creator is still admin and not explicitly forbidden to edit accounts + if ($this->creator) $this->_check_admin($this->is_user ? 'account_access' : 'group_access',32); + + if ($this->account === '--not-existing') + { + return $this->delete_not_existing($check_only); + } $account_id = admin_cmd::parse_account($this->account,$this->is_user); admin_cmd::_instanciate_accounts(); $account_lid = admin_cmd::$accounts->id2name($account_id); @@ -57,28 +64,9 @@ class admin_cmd_delete_account extends admin_cmd { $new_user = admin_cmd::parse_account($this->new_user,true); // true = user, no group } - // check creator is still admin and not explicitly forbidden to edit accounts - if ($this->creator) $this->_check_admin($this->is_user ? 'account_access' : 'group_access',32); - if ($check_only) return true; - // delete the account - $GLOBALS['hook_values'] = array( - 'account_id' => $account_id, - 'account_lid' => $account_lid, - 'account_name'=> $account_lid, // depericated name for deletegroup hook - 'new_owner' => (int)$new_user, // deleteaccount only - 'location' => $this->is_user ? 'deleteaccount' : 'deletegroup', - ); - // first all other apps, then preferences and admin - foreach(array_merge(array_diff(array_keys($GLOBALS['egw_info']['apps']),array('preferences','admin')),array('preferences','admin')) as $app) - { - Api\Hooks::single($GLOBALS['hook_values'],$app); - } - // store old content at time of deletion - $this->old = $GLOBALS['egw']->accounts->read($account_id); - - $GLOBALS['egw']->accounts->delete($account_id); + $this->delete_account($this->is_user, $account_id, $account_lid, $new_user); if ($account_id < 0) { @@ -87,6 +75,140 @@ class admin_cmd_delete_account extends admin_cmd return lang("Account '%1' deleted.",$account_lid)."\n\n"; } + /** + * Delete all in account repository no longer existing accounts + * + * @param boolean $check_only =false only run the checks (and throw the exceptions), but not the command itself + * @return string with success message + */ + protected function delete_not_existing($check_only=false) + { + admin_cmd::_instanciate_accounts(); + $repo_ids = array(); + if (($all_accounts = admin_cmd::$accounts->search(array('type'=>'both','active'=>false)))) + { + foreach($all_accounts as $account) + { + $repo_ids[] = $account['account_id']; + } + } + //print_r($repo_ids); + + static $ignore = array( + 'egw_admin_queue' => array('cmd_account'), // contains also deleted accounts / admin history + ); + $account_ids = array(); + $account_cols = admin_cmd_change_account_id::get_account_colums(); + //print_r($account_cols); + foreach($account_cols as $app => $data) + { + if (!isset($GLOBALS['egw_info']['apps'][$app])) continue; // $app is not installed + + $db = clone($GLOBALS['egw']->db); + $db->set_app($app); + if ($check_only) $db->log_updates = $db->readonly = true; + + foreach($data as $table => $columns) + { + $db->column_definitions = $db->get_table_definitions($app,$table); + $db->column_definitions = $db->column_definitions['fd']; + if (!$columns || substr($table, 0, 4) != 'egw_') + { + //echo "$app: $table no columns with account-id's\n"; + continue; // noting to do for this table + } + // never check / use accounts-table (not used for LDAP/AD, all in for SQL) + if ($table == 'egw_accounts') continue; + + if (!is_array($columns)) $columns = array($columns); + + foreach($columns as $column) + { + $type = $where = null; + if (is_array($column)) + { + $type = $column['.type']; + unset($column['.type']); + $where = $column; + $column = array_shift($where); + } + if (in_array($type, array('abs','prefs'))) // would need special handling + { + continue; + } + if (isset($ignore[$table]) && in_array($column, $ignore[$table])) + { + continue; + } + if ($table == 'egw_acl' && $column == 'acl_location') + { + $where[] = "acl_appname='phpgw_group'"; + } + $ids = array(); + foreach($rs=$db->select($table, 'DISTINCT '.$column, $where, __LINE__, __FILE__) as $row) + { + foreach(explode(',', $row[$column]) as $account_id) + { + if ($account_id && is_numeric($account_id) && !in_array($account_id, $repo_ids)) + { + $account_ids[$account_id] = $ids[] = $account_id; + } + } + } + if ($ids) echo $rs->sql.": ".implode(', ', $ids)."\n"; + } + } + } + //print_r($account_ids); + + asort($account_ids, SORT_NUMERIC); + echo count($account_ids)." not existing account_id's found in EGroupware, ".count($repo_ids)." exist in account repository\n". + "--> following should be deleted: ".implode(', ', $account_ids)."\n"; + + if ($check_only) return true; + + if ($this->new_user) + { + $new_user = admin_cmd::parse_account($this->new_user,true); // true = user, no group + } + foreach($account_ids as $account_id) + { + $this->delete_account($account_id > 0, $account_id, 'account'.$account_id, $account_id > 0 ? $new_user : null); + } + Api\Cache::flush(Api\Cache::INSTANCE); + + return lang("Total of %1 accounts deleted.", count($account_ids))."\n"; + } + + /** + * Delete account incl. calling all necessary hooks + * + * @param boolean $is_user true: user, false: group + * @param int $account_id numerical account_id of use to delete + * @param string $account_lid =null account_lid of user to delete + * @param int $new_user =null if given account_id to transfer data to + */ + protected function delete_account($is_user, $account_id, $account_lid=null, $new_user=null) + { + // delete the account + $GLOBALS['hook_values'] = array( + 'account_id' => $account_id, + 'account_lid' => $account_lid, + 'account_name'=> $account_lid, // depericated name for deletegroup hook + 'new_owner' => (int)$new_user, // deleteaccount only + 'location' => $is_user ? 'deleteaccount' : 'deletegroup', + ); + // first all other apps, then preferences and admin + foreach(array_merge(array_diff(array_keys($GLOBALS['egw_info']['apps']),array('preferences','admin')),array('preferences','admin')) as $app) + { + Api\Hooks::single($GLOBALS['hook_values'], $app, true); + } + // store old content at time of deletion + $this->old = $GLOBALS['egw']->accounts->read($account_id); + + $GLOBALS['egw']->accounts->delete($account_id); + } + /** * Return a title / string representation for a given command, eg. to display it * From fb3d2cc4f3dd6781b9eccd06982bbc07f45bd4c7 Mon Sep 17 00:00:00 2001 From: nathangray Date: Wed, 27 Feb 2019 09:59:40 -0700 Subject: [PATCH 04/11] Etemplate - Show button icon if button goes from readonly -> clickable --- api/js/etemplate/et2_widget_button.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/js/etemplate/et2_widget_button.js b/api/js/etemplate/et2_widget_button.js index 71a3ff0c14..a3a476dea5 100644 --- a/api/js/etemplate/et2_widget_button.js +++ b/api/js/etemplate/et2_widget_button.js @@ -225,7 +225,7 @@ var et2_button = (function(){ "use strict"; return et2_baseWidget.extend([et2_II { this.options.readonly = _ro; - if (this.image) + if (this.options.image || this.options.ro_image) { this.update_image(); } From 75fa8f4d05737a8eec766cbe74d44e2fff56a8ad Mon Sep 17 00:00:00 2001 From: nathangray Date: Wed, 27 Feb 2019 13:43:33 -0700 Subject: [PATCH 05/11] Etemplate - dependencies for server side diff --- composer.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 2f46c925d4..eaa471ad42 100644 --- a/composer.json +++ b/composer.json @@ -40,7 +40,7 @@ { "type": "pear", "url": "https://pear.horde.org" - } + } ], "config": { }, @@ -64,6 +64,7 @@ "pear-pear.horde.org/horde_mapi": "^1.0.9", "pear-pear.horde.org/horde_managesieve": "^1.0.2", "pear-pear.horde.org/horde_crypt": "^2.7.9", + "pear-pear.horde.org/horde_text_diff": "^2.2", "pear/pear": "*", "pear/auth_sasl": "*", "pear/xml_feed_parser": "^1.0.5", @@ -74,6 +75,7 @@ "bower-asset/jquery-touchswipe": "1.6.*", "bower-asset/jquery-ui":"=1.11.2", "bower-asset/cropper":"2.3.*", + "bower-asset/diff2html": "^2.7", "npm-asset/as-jqplot" : "1.0.*", "npm-asset/gridster":"0.5.*", "adldap2/adldap2": "=4.0.4", @@ -103,5 +105,7 @@ "installer-paths": { "{$name}/": ["type:egroupware-app"] } - } + }, + "minimum-stability": "dev", + "prefer-stable": true } From 605e49579fd0db14d7ac1ff38b9ad7e08c94ece8 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Thu, 28 Feb 2019 09:32:19 +0100 Subject: [PATCH 06/11] * Setup: fix failed/partial restores for charsets not utf-8 caused by NULL converted to "" (empty string) --- api/src/Translation.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/api/src/Translation.php b/api/src/Translation.php index ab6a9fc1b7..3ced7289c5 100644 --- a/api/src/Translation.php +++ b/api/src/Translation.php @@ -851,10 +851,14 @@ class Translation * @param string|boolean $from charset $data is in or False if it should be detected * @param string|boolean $to charset to convert to or False for the system-charset the converted string * @param boolean $check_to_from =true internal to bypass all charset replacements - * @return string|array converted string(s) from $data + * @return NULL|string|array converted string(s) from $data */ static function convert($data,$from=False,$to=False,$check_to_from=true) { + if (empty($data)) + { + return $data; // no need for any charset conversation (NULL, '', 0, '0', array()) + } if ($check_to_from) { if ($from) $from = strtolower($from); @@ -925,7 +929,8 @@ class Translation { foreach($data as $key => $str) { - $ret[$key] = self::convert($str,$from,$to,false); // false = bypass the above checks, as they are already done + $ret[$key] = empty($str) ? $str : // do NOT convert null to '' (other empty values need no conversation too) + self::convert($str,$from,$to,false); // false = bypass the above checks, as they are already done } return $ret; } From d43e10934a5142dee9c1fd5c66766fc58e712e03 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Thu, 28 Feb 2019 10:13:37 +0100 Subject: [PATCH 07/11] updated composer.lock after adding the diff stuff to composer.json --- composer.lock | 54 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index f6ace3232a..9a6b63e85b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0129834b90f9bcd8da3186b801634419", + "content-hash": "4b4154e1060aa6ff13cd127255332df4", "packages": [ { "name": "adldap2/adldap2", @@ -114,6 +114,22 @@ "zoom" ] }, + { + "name": "bower-asset/diff2html", + "version": "v2.7.0", + "source": { + "type": "git", + "url": "https://github.com/rtfpessoa/diff2html.git", + "reference": "2512e72f32b709a3dc0615a2d5b32183dd0b3b6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rtfpessoa/diff2html/zipball/2512e72f32b709a3dc0615a2d5b32183dd0b3b6a", + "reference": "2512e72f32b709a3dc0615a2d5b32183dd0b3b6a", + "shasum": "" + }, + "type": "bower-asset-library" + }, { "name": "bower-asset/fastclick", "version": "v1.0.6", @@ -1684,6 +1700,37 @@ ], "description": "Support classes not tied to Horde but is used by it. These classes can be used outside of Horde as well." }, + { + "name": "pear-pear.horde.org/Horde_Text_Diff", + "version": "2.2.0", + "dist": { + "type": "file", + "url": "https://pear.horde.org/get/Horde_Text_Diff-2.2.0.tgz", + "reference": null, + "shasum": null + }, + "require": { + "pear-pear.horde.org/horde_exception": "<3.0.0.0", + "pear-pear.horde.org/horde_util": "<3.0.0.0", + "php": "<8.0.0.0" + }, + "replace": { + "pear-horde/horde_text_diff": "== 2.2.0.0" + }, + "type": "pear-library", + "autoload": { + "classmap": [ + "" + ] + }, + "include-path": [ + "/" + ], + "license": [ + "LGPL-2.1" + ], + "description": "A text-based diff engine and renderers for multiple diff output formats." + }, { "name": "pear-pear.horde.org/Horde_Text_Flowed", "version": "2.0.3", @@ -2347,9 +2394,8 @@ ], "packages-dev": [], "aliases": [], - "minimum-stability": "stable", + "minimum-stability": "dev", "stability-flags": { - "php": 15, "egroupware/collabora": 20, "egroupware/projectmanager": 20, "egroupware/tracker": 20, @@ -2357,7 +2403,7 @@ "egroupware/activesync": 20, "egroupware/adodb-php": 20 }, - "prefer-stable": false, + "prefer-stable": true, "prefer-lowest": false, "platform": { "php": ">=7.0,<=8.0.0alpha1", From 3a904b16bd1e16bbe45e30cebb2ed81275783da0 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Thu, 28 Feb 2019 10:37:37 +0100 Subject: [PATCH 08/11] try fixing Scrutinizer composer install problem --- composer.json | 1 + composer.lock | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index eaa471ad42..38c94618a4 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,6 @@ { "name": "egroupware/egroupware", + "version": "dev-master", "description": "EGroupware extends a classic groupware with an integreted CRM-system, a secure file-server and Collabora Online Office.", "keywords": [ "groupware", diff --git a/composer.lock b/composer.lock index 9a6b63e85b..6b5ff3d6cf 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4b4154e1060aa6ff13cd127255332df4", + "content-hash": "ae8efa0b4a05424ce6c63e679ff7f703", "packages": [ { "name": "adldap2/adldap2", From 09e90b12356b30e96ccdcfb4b9f6aa62d8841c3f Mon Sep 17 00:00:00 2001 From: Hadi Nategh Date: Thu, 28 Feb 2019 11:47:00 +0100 Subject: [PATCH 09/11] Take ascii mode into account before purifying the value --- api/src/Etemplate/Widget/HtmlArea.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/api/src/Etemplate/Widget/HtmlArea.php b/api/src/Etemplate/Widget/HtmlArea.php index d73a935aba..d8c0367e24 100644 --- a/api/src/Etemplate/Widget/HtmlArea.php +++ b/api/src/Etemplate/Widget/HtmlArea.php @@ -86,10 +86,15 @@ class HtmlArea extends Etemplate\Widget if (!$this->is_readonly($cname, $form_name)) { - $value = Api\Html\HtmLawed::purify( - self::get_array($content, $form_name), - $this->attrs['validation_rules'] - ); + $value = self::get_array($content, $form_name); + // only purify for html, mode "ascii" is NO html and content get lost! + if ($this->attrs['mode'] != 'ascii') + { + $value = Api\Html\HtmLawed::purify( + self::get_array($content, $form_name), + $this->attrs['validation_rules'] + ); + } $valid =& self::get_array($validated, $form_name, true); if (true) $valid = $value; } From b19e71b28d644566ee38672a3510c8765365c0ed Mon Sep 17 00:00:00 2001 From: nathangray Date: Thu, 28 Feb 2019 09:30:47 -0700 Subject: [PATCH 10/11] Etemplate - if a button has an image but no readonly image set, use the normal image when button is readonly --- api/js/etemplate/et2_widget_button.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/js/etemplate/et2_widget_button.js b/api/js/etemplate/et2_widget_button.js index a3a476dea5..c93e705264 100644 --- a/api/js/etemplate/et2_widget_button.js +++ b/api/js/etemplate/et2_widget_button.js @@ -168,7 +168,7 @@ var et2_button = (function(){ "use strict"; return et2_baseWidget.extend([et2_II if(!this.isInTree() || !this.options.background_image && this.image == null) return; if (typeof _image == 'undefined') - _image = this.options.readonly ? this.options.ro_image : this.options.image; + _image = this.options.readonly ? (this.options.ro_image || this.options.image) : this.options.image; // Silently blank for percentages instead of warning about missing image - use a progress widget if(_image.match(/^[0-9]+\%$/)) From 24003deafa91dd4650ac6994b60dc1998633a80a Mon Sep 17 00:00:00 2001 From: nathangray Date: Thu, 28 Feb 2019 11:38:43 -0700 Subject: [PATCH 11/11] Remove dependency on pear/text_diff, we use pear-pear.horde.org/horde_text_diff everywhere now --- composer.json | 1 - composer.lock | 42 +++--------------------------------------- 2 files changed, 3 insertions(+), 40 deletions(-) diff --git a/composer.json b/composer.json index 38c94618a4..66efcd01d6 100644 --- a/composer.json +++ b/composer.json @@ -70,7 +70,6 @@ "pear/auth_sasl": "*", "pear/xml_feed_parser": "^1.0.5", "pear/log": "*", - "pear/text_diff": "^1.2.2", "bower-asset/jquery": "^1.12.4", "bower-asset/fastclick":"1.0.*", "bower-asset/jquery-touchswipe": "1.6.*", diff --git a/composer.lock b/composer.lock index 6b5ff3d6cf..a7c868dfd4 100644 --- a/composer.lock +++ b/composer.lock @@ -1,10 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "ae8efa0b4a05424ce6c63e679ff7f703", + "content-hash": "2b00ad598700859fd0600f10fd8967bb", "packages": [ { "name": "adldap2/adldap2", @@ -787,15 +787,12 @@ "php": ">=5.4.0" }, "type": "library", + "notification-url": "https://packagist.org/downloads/", "license": [ "AGPL-3.0" ], "description": "Z-Push is an open-source application to synchronize ActiveSync compatible devices", "homepage": "http://z-push.org/", - "support": { - "source": "https://github.com/EGroupware/z-push/tree/master", - "issues": "https://github.com/EGroupware/z-push/issues" - }, "time": "2019-02-11T19:26:21+00:00" }, { @@ -2256,39 +2253,6 @@ "description": "More info available on: http://pear.php.net/package/Structures_Graph", "time": "2015-07-20T20:05:12+00:00" }, - { - "name": "pear/text_diff", - "version": "v1.2.2", - "source": { - "type": "git", - "url": "https://github.com/pear/Text_Diff.git", - "reference": "d12474df481bb89f52b02ba0e3fae504ce5d6d51" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pear/Text_Diff/zipball/d12474df481bb89f52b02ba0e3fae504ce5d6d51", - "reference": "d12474df481bb89f52b02ba0e3fae504ce5d6d51", - "shasum": "" - }, - "type": "library", - "autoload": { - "classmap": [ - "Text/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0" - ], - "description": "Engine for performing and rendering text diffs", - "homepage": "http://pear.php.net/package/Text_Diff", - "keywords": [ - "PEAR", - "diff", - "text" - ], - "time": "2017-03-08T15:07:59+00:00" - }, { "name": "pear/xml_feed_parser", "version": "v1.0.5",