diff --git a/api/js/etemplate/et2_core_DOMWidget.js b/api/js/etemplate/et2_core_DOMWidget.js index 4da381cc74..11135a327b 100644 --- a/api/js/etemplate/et2_core_DOMWidget.js +++ b/api/js/etemplate/et2_core_DOMWidget.js @@ -468,7 +468,7 @@ var et2_DOMWidget = (function(){ "use strict"; return et2_widget.extend(et2_IDOM * the more widget-specific parts. * * @param {object} actions {ID: {attributes..}+} map of egw action information - * @see etemplate/inc/class.etemplate_widget_nextmatch->egw_actions() + * @see api/src/Etemplate/Widget/Nextmatch.php egw_actions() method */ set_actions: function(actions) { diff --git a/api/js/etemplate/et2_extension_customfields.js b/api/js/etemplate/et2_extension_customfields.js index 6ee4e6c5a8..27923da3a8 100644 --- a/api/js/etemplate/et2_extension_customfields.js +++ b/api/js/etemplate/et2_extension_customfields.js @@ -627,7 +627,7 @@ var et2_customfields_list = (function(){ "use strict"; return et2_valueWidget.ex // Filemanager select { label: '', - method: 'etemplate_widget_link::link_existing', + method: 'EGroupware\\Api\\Etemplate\\Widget\\Link::link_existing', method_id: attrs.path, button_label: egw.lang('Link') },{type: 'vfs-select'}); diff --git a/api/js/etemplate/et2_extension_nextmatch_controller.js b/api/js/etemplate/et2_extension_nextmatch_controller.js index 58e18b449b..4295331994 100644 --- a/api/js/etemplate/et2_extension_nextmatch_controller.js +++ b/api/js/etemplate/et2_extension_nextmatch_controller.js @@ -390,7 +390,7 @@ var et2_nextmatch_controller = (function(){ "use strict"; return et2_dataview_co } // Link the entries - self.egw.json(self.egw.getAppName()+".etemplate_widget_link.ajax_link.etemplate", + self.egw.json("EGroupware\\Api\\Etemplate\\Widget\\Link::ajax_link", dropped.id.split('::').concat([links]), function(result) { if(result) diff --git a/api/js/etemplate/et2_widget_entry.js b/api/js/etemplate/et2_widget_entry.js index 93f11172aa..71d49243be 100644 --- a/api/js/etemplate/et2_widget_entry.js +++ b/api/js/etemplate/et2_widget_entry.js @@ -16,7 +16,7 @@ /** * A widget to display a value from an entry * - * Since we have etemplate_widget_transformer, this client side widget exists + * Since we have Etemplate\Widget\Transformer, this client side widget exists * mostly to resolve the problem where the ID for the entry widget is the same * as the widget where you actually set the value, which prevents transformer * from working. diff --git a/api/js/etemplate/et2_widget_file.js b/api/js/etemplate/et2_widget_file.js index e27f2fa3ec..2c7e8f6d4a 100644 --- a/api/js/etemplate/et2_widget_file.js +++ b/api/js/etemplate/et2_widget_file.js @@ -139,7 +139,7 @@ var et2_file = (function(){ "use strict"; return et2_inputWidget.extend( beforeSend: function(form) { return self.beforeSend(form);}, - target: egw.ajaxUrl(self.egw().getAppName()+".etemplate_widget_file.ajax_upload.etemplate"), + target: egw.ajaxUrl("EGroupware\\Api\\Etemplate\\Widget\\File::ajax_upload"), query: function(file) {return self.beforeSend(file);}, // Disable checking for already uploaded chunks testChunks: false diff --git a/api/js/etemplate/et2_widget_htmlarea.js b/api/js/etemplate/et2_widget_htmlarea.js index 27d1d66932..c968ed914d 100644 --- a/api/js/etemplate/et2_widget_htmlarea.js +++ b/api/js/etemplate/et2_widget_htmlarea.js @@ -127,7 +127,7 @@ var et2_htmlarea = (function(){ "use strict"; return et2_inputWidget.extend([et2 } else if (this.options.imageUpload[0] !== '/' && this.options.imageUpload.substr(0, 4) != 'http') { - self.options.config.imageUploadUrl = egw.ajaxUrl(self.egw().getAppName()+".etemplate_widget_vfs.ajax_htmlarea_upload.etemplate")+ + self.options.config.imageUploadUrl = egw.ajaxUrl("EGroupware\\Api\\Etemplate\\Widget\\Vfs::ajax_htmlarea_upload")+ '&request_id='+self.getInstanceManager().etemplate_exec_id+'&widget_id='+this.options.imageUpload; self.options.config.imageUploadUrl = self.options.config.imageUploadUrl.substr(egw.webserverUrl.length+1); } diff --git a/api/js/etemplate/et2_widget_itempicker.js b/api/js/etemplate/et2_widget_itempicker.js index 6f0e51e83f..d8d30ca8ce 100755 --- a/api/js/etemplate/et2_widget_itempicker.js +++ b/api/js/etemplate/et2_widget_itempicker.js @@ -236,7 +236,7 @@ var et2_itempicker = (function(){ "use strict"; return et2_inputWidget.extend( this.itemlist.addClass("loading"); this.clear.css("display", "inline-block"); - egw._json("etemplate_widget_itempicker::ajax_item_search::etemplate", + egw._json("EGroupware\\Api\\Etemplate\\Widget\\ItemPicker::ajax_item_search", [this.current_app, '', request.term, request.options], this.queryResults, this,true,this diff --git a/api/js/etemplate/et2_widget_link.js b/api/js/etemplate/et2_widget_link.js index f358711d56..1c1cc75450 100644 --- a/api/js/etemplate/et2_widget_link.js +++ b/api/js/etemplate/et2_widget_link.js @@ -178,7 +178,7 @@ var et2_link_to = (function(){ "use strict"; return et2_inputWidget.extend( // Filemanager select var select_attrs = { - method: 'etemplate_widget_link::link_existing', + method: 'EGroupware\\Api\\Etemplate\\Widget\\Link::link_existing', method_id: function() { return self.options.value.to_app + ':' + self.options.value.to_id;}, button_label: egw.lang('Link') }; @@ -296,7 +296,7 @@ var et2_link_to = (function(){ "use strict"; return et2_inputWidget.extend( return; } - var request = egw.json(self.egw().getAppName()+".etemplate_widget_link.ajax_link.etemplate", + var request = egw.json("EGroupware\\Api\\Etemplate\\Widget\\Link::ajax_link", [values.to_app, values.to_id, links], self._link_result, self, @@ -939,7 +939,7 @@ var et2_link_entry = (function(){ "use strict"; return et2_inputWidget.extend( // Remove specific display and revert to CSS file // show() would use inline, should be inline-block this.clear.css('display',''); - this.request = egw.json(egw_getAppName() + ".etemplate_widget_link.ajax_link_search.etemplate", + this.request = egw.json("EGroupware\\Api\\Etemplate\\Widget\\Link::ajax_link_search", [this.app_select.val(), '', request.term, request.options], this._results, this,true,this @@ -1036,7 +1036,7 @@ var et2_link_entry = (function(){ "use strict"; return et2_inputWidget.extend( // If a link array was passed in, don't make the ajax call if(typeof _links == 'undefined') { - var request = egw.json(self.egw().getAppName()+".etemplate_widget_link.ajax_link.etemplate", + var request = egw.json("EGroupware\\Api\\Etemplate\\Widget\\Link::ajax_link", [values.to_app, values.to_id, links], self._link_result, this, @@ -1346,7 +1346,7 @@ var et2_link_string = (function(){ "use strict"; return expose(et2_valueWidget.e { _value.only_app = this.options.only_app; } - this.egw().jsonq(this.egw().getAppName()+'.etemplate_widget_link.ajax_link_list', [_value], this.set_value, this); + this.egw().jsonq('EGroupware\\Api\\Etemplate\\Widget\\Link::ajax_link_list', [_value], this.set_value, this); return; }, /** @@ -1549,7 +1549,7 @@ var et2_link_list = (function(){ "use strict"; return et2_link_string.extend( return; } remark.addClass("loading"); - var request = egw.json(self.egw().getAppName() + ".etemplate_widget_link.ajax_link_comment.etemplate", + var request = egw.json("EGroupware\\Api\\Etemplate\\Widget\\Link::ajax_link_comment", [link_id, comment], function() { if(remark) @@ -1623,7 +1623,7 @@ var et2_link_list = (function(){ "use strict"; return et2_link_string.extend( // Download ZIP window.location = self.egw().link('/index.php',{ - menuaction: 'etemplate.etemplate_widget_link.download_zip', + menuaction: 'EGroupware\\Api\\Etemplate\\Widget\\Link::download_zip', app: self.value.to_app, id: self.value.to_id }); @@ -1917,7 +1917,7 @@ var et2_link_list = (function(){ "use strict"; return et2_link_string.extend( } if(typeof link_id != "object") { - egw.json(this.egw().getAppName()+".etemplate_widget_link.ajax_delete.etemplate", [link_id], + egw.json("EGroupware\\Api\\Etemplate\\Widget\\Link::ajax_delete", [link_id], function(data) { if(data) {row.slideUp(row.remove);}} ).sendRequest(); } diff --git a/api/js/etemplate/et2_widget_selectbox.js b/api/js/etemplate/et2_widget_selectbox.js index 69835fe355..96bb37c2fe 100644 --- a/api/js/etemplate/et2_widget_selectbox.js +++ b/api/js/etemplate/et2_widget_selectbox.js @@ -945,7 +945,7 @@ jQuery.extend(et2_selectbox, //(function(){ "use strict"; return /** * Some static options, no need to transfer them over and over. * We still need the same thing on the server side to validate, so they - * have to match. See etemplate_widget_menupopup::typeOptions() + * have to match. See Etemplate\Widget\Select::typeOptions() * The type specific legacy options wind up in attrs.other. * * @param {type} widget @@ -1132,7 +1132,7 @@ jQuery.extend(et2_selectbox, //(function(){ "use strict"; return // one widget listening for the response by the time it gets back, // and we can't do that when it's queued. var req = egw.json( - widget.getInstanceManager().app+'.etemplate_widget_menupopup.ajax_get_options.etemplate', + 'EGroupware\\Api\\Etemplate\\Widget\\Select::ajax_get_options', [widget._type,options_string,attrs.value] ).sendRequest(!in_nextmatch); if(typeof cache === 'undefined') diff --git a/api/js/etemplate/et2_widget_taglist.js b/api/js/etemplate/et2_widget_taglist.js index 7428907174..4b6a1b8194 100644 --- a/api/js/etemplate/et2_widget_taglist.js +++ b/api/js/etemplate/et2_widget_taglist.js @@ -50,7 +50,7 @@ var et2_taglist = (function(){ "use strict"; return et2_selectbox.extend([et2_IR "autocomplete_url": { "name": "Autocomplete source", "type": "string", - "default": "home.etemplate_widget_taglist.ajax_search.etemplate", + "default": "EGroupware\\Api\\Etemplate\\Widget\\Taglist::ajax_search", "description": "Menuaction (app.class.function) for autocomplete data source. Must return actual JSON, and nothing more." }, "autocomplete_params": { @@ -838,7 +838,7 @@ var et2_taglist_account = (function(){ "use strict"; return et2_taglist.extend( { attributes: { "autocomplete_url": { - "default": "home.etemplate_widget_taglist.ajax_search.etemplate" + "default": "EGroupware\\Api\\Etemplate\\Widget\\Taglist::ajax_search" }, allowFreeEntries: { "default": false, @@ -1008,7 +1008,7 @@ var et2_taglist_email = (function(){ "use strict"; return et2_taglist.extend( { attributes: { "autocomplete_url": { - "default": "home.etemplate_widget_taglist.ajax_email.etemplate" + "default": "EGroupware\\Api\\Etemplate\\Widget\\Taglist::ajax_email" }, "autocomplete_params": { "default": {} diff --git a/api/js/etemplate/et2_widget_tree.js b/api/js/etemplate/et2_widget_tree.js index a4e01ebe95..03b98ee3a7 100644 --- a/api/js/etemplate/et2_widget_tree.js +++ b/api/js/etemplate/et2_widget_tree.js @@ -25,7 +25,7 @@ /** * Tree widget * - * For syntax of nodes supplied via sel_optons or autoloading refer to etemplate_widget_tree class. + * For syntax of nodes supplied via sel_optons or autoloading refer to Etemplate\Widget\Tree class. * * @augments et2_inputWidget */ diff --git a/api/js/etemplate/et2_widget_url.js b/api/js/etemplate/et2_widget_url.js index cb7f7028d8..68c4afcad6 100644 --- a/api/js/etemplate/et2_widget_url.js +++ b/api/js/etemplate/et2_widget_url.js @@ -44,7 +44,7 @@ var et2_url = (function(){ "use strict"; return et2_textbox.extend( * * Using \042 instead of " to NOT stall minifyer! * - * Same preg is in etemplate_widget_url PHP class! + * Same preg is in Etemplate\Widget\Url PHP class! */ EMAIL_PREG: new RegExp(/^(([^\042',<][^,<]+|\042[^\042]+\042|\'[^\']+\'|)\s?<)?[^\x00-\x20()<>@,;:\042\[\]]+@([a-z0-9ÄÖÜäöüß](|[a-z0-9ÄÖÜäöüß_-]*[a-z0-9ÄÖÜäöüß])\.)+[a-z]{2,}>?$/i), /** @@ -317,7 +317,7 @@ var et2_url_ro = (function(){ "use strict"; return et2_valueWidget.extend([et2_I // need to preserve the original value somehow // as it's been used for add contact plus feature this.span.attr('title',_value); - + this.span.text(val.replace(/"/g,'')); this.span.append(""+ _value.replace(val,'') diff --git a/api/js/etemplate/et2_widget_vfs.js b/api/js/etemplate/et2_widget_vfs.js index 95e952ebb6..82ab6ffa85 100644 --- a/api/js/etemplate/et2_widget_vfs.js +++ b/api/js/etemplate/et2_widget_vfs.js @@ -654,7 +654,7 @@ var et2_vfsUpload = (function(){ "use strict"; return et2_file.extend( legacyOptions: ["mime"], asyncOptions: { - target: egw.ajaxUrl(self.egw().getAppName()+".etemplate_widget_vfs.ajax_upload.etemplate") + target: egw.ajaxUrl("EGroupware\\Api\\Etemplate\\Widget\\Vfs::ajax_upload") }, /** diff --git a/api/src/Etemplate/Widget/Link.php b/api/src/Etemplate/Widget/Link.php index c6772f1c69..4b9e683620 100644 --- a/api/src/Etemplate/Widget/Link.php +++ b/api/src/Etemplate/Widget/Link.php @@ -176,7 +176,7 @@ class Link extends Etemplate\Widget $response->data(is_array($id) ? $id : $result !== false); } - public function ajax_link_list($value) + public static function ajax_link_list($value) { $app = $value['to_app']; $id = $value['to_id']; @@ -256,7 +256,7 @@ class Link extends Etemplate\Widget } } - public function ajax_delete($value) + public static function ajax_delete($value) { $response = egw_json_response::get(); $response->data(Api\Link::unlink($value)); @@ -270,7 +270,7 @@ class Link extends Etemplate\Widget * the entry has no linked files, the ZIP will still be returned, but it will * be empty. */ - public function download_zip() + public static function download_zip() { $app = $_GET['app']; $id = $_GET['id']; diff --git a/phpgwapi/inc/class.egw_json.inc.php b/phpgwapi/inc/class.egw_json.inc.php index 6e155dceb1..bf8fdff5ef 100644 --- a/phpgwapi/inc/class.egw_json.inc.php +++ b/phpgwapi/inc/class.egw_json.inc.php @@ -94,7 +94,14 @@ class egw_json_request if (strpos($menuaction,'::') !== false && strpos($menuaction,'.') === false) // static method name app_something::method { @list($className,$functionName,$handler) = explode('::',$menuaction); - list($appName) = explode('_',$className); + if (substr($className, 0, 11) == 'EGroupware\\') + { + list(,$appName) = explode('\\', strtolower($className)); + } + else + { + list($appName) = explode('_',$className); + } // Check for a real static method, avoid instanciation if it is $m = new ReflectionMethod($menuaction); @@ -137,9 +144,10 @@ class egw_json_request if(substr($className,0,4) != 'ajax' && substr($className,-4) != 'ajax' && $menuaction != 'etemplate.etemplate.process_exec' && substr($functionName,0,4) != 'ajax' || - !preg_match('/^[A-Za-z0-9_-]+(\.[A-Za-z0-9_]+\.|::)[A-Za-z0-9_]+$/',$menuaction)) + !preg_match('/^[A-Za-z0-9_\\\\-]+(\.[A-Za-z0-9_\\\\]+\.|::)[A-Za-z0-9_]+$/',$menuaction)) { // stopped for security reasons + error_log("className='$className', functionName='$functionName', menuaction='$menuaction'"); error_log($_SERVER['PHP_SELF']. ' stopped for security reason. '.$menuaction.' is not valid. class- or function-name must start with ajax!!!'); // send message also to the user throw new Exception($_SERVER['PHP_SELF']. ' stopped for security reason. '.$menuaction.' is not valid. class- or function-name must start with ajax!!!');