From ec4899e6179f2d9b368e6fc04041dd72c2ac2596 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 24 Feb 2010 22:16:17 +0000 Subject: [PATCH 1/6] OStatus: disable HTMLPurify cache unless we've configured a writable path for it. Updated plugin README with available config options. Cleanup for a bad element fallback lookup in Activity --- lib/activity.php | 26 ++++++----- plugins/OStatus/README | 50 +++++++++++++-------- plugins/OStatus/classes/Ostatus_profile.php | 22 ++++++++- 3 files changed, 66 insertions(+), 32 deletions(-) diff --git a/lib/activity.php b/lib/activity.php index 33932ad0ef..25727bf2b5 100644 --- a/lib/activity.php +++ b/lib/activity.php @@ -167,16 +167,18 @@ class PoCo PoCo::NS ); - $formatted = ActivityUtils::childContent( - $addressEl, - PoCoAddress::FORMATTED, - self::NS - ); + if (!empty($addressEl)) { + $formatted = ActivityUtils::childContent( + $addressEl, + PoCoAddress::FORMATTED, + self::NS + ); - if (!empty($formatted)) { - $address = new PoCoAddress(); - $address->formatted = $formatted; - return $address; + if (!empty($formatted)) { + $address = new PoCoAddress(); + $address->formatted = $formatted; + return $address; + } } return null; @@ -292,7 +294,7 @@ class ActivityUtils * @return string related link, if any */ - static function getLink($element, $rel, $type=null) + static function getLink(DOMNode $element, $rel, $type=null) { $links = $element->getElementsByTagnameNS(self::ATOM, self::LINK); @@ -320,7 +322,7 @@ class ActivityUtils * @return DOMElement found element or null */ - static function child($element, $tag, $namespace=self::ATOM) + static function child(DOMNode $element, $tag, $namespace=self::ATOM) { $els = $element->childNodes; if (empty($els) || $els->length == 0) { @@ -345,7 +347,7 @@ class ActivityUtils * @return string content of the child */ - static function childContent($element, $tag, $namespace=self::ATOM) + static function childContent(DOMNode $element, $tag, $namespace=self::ATOM) { $el = self::child($element, $tag, $namespace); diff --git a/plugins/OStatus/README b/plugins/OStatus/README index cbf3adbb9c..09a59e3497 100644 --- a/plugins/OStatus/README +++ b/plugins/OStatus/README @@ -2,23 +2,37 @@ Plugin to support importing updates from external RSS and Atom feeds into your t Uses PubSubHubbub for push feed updates; currently non-PuSH feeds cannot be subscribed. +Configuration options available: + +$config['ostatus']['hub'] + (default internal hub) + Set to URL of an external PuSH hub to use it instead of our internal hub. + +$config['ostatus']['hub_retries'] + (default 0) + Number of times to retry a PuSH send to consumers if using internal hub + +$config['ostatus']['purify_cache'] + (default cache disabled) + Set to a writable cache directory for HTMLPurifier's configuration settings, can speed up processing of remote messages (have not tested by how much) + + +For testing, shouldn't be used in production: + +$config['ostatus']['skip_signatures'] + (default use signatures) + Disable generation and validation of Salmon magicenv signatures + +$config['feedsub']['nohub'] + (default require hub) + Allow low-level feed subscription setup for feeds without hubs. + Not actually usable at this stage, OStatus will check for hubs too + and we have no polling backend. + + Todo: -* set feed icon avatar for actual profiles as well as for preview -* use channel image and/or favicon for avatar? -* garbage-collect subscriptions that are no longer being used -* administrative way to kill feeds? -* functional l10n -* clean up subscription form look and workflow -* use ajax for test/preview in subscription form -* rssCloud support? (Does anything use it that doesn't support PuSH as well?) -* possibly a polling daemon to support non-PuSH feeds? -* likely problems with multiple feeds from the same site, such as category feeds on a blog - (currently each feed would publish a separate notice on a separate profile, but pointing to the same post URI.) - (could use the local URI I guess, but that's so icky!) -* problems with Atom feeds that list but don't have the type - (such as http://atomgen.appspot.com/feed/5 demo feed); currently it's not recognized and we end up with the feed's master URI -* make it easier to see what you're subscribed to and unsub from things -* saner treatment of fullname/nickname? +* fully functional l10n +* redo non-OStatus feed support +** rssCloud support? +** possibly a polling daemon to support non-PuSH feeds? * make use of tags/categories from feeds -* update feed profile data when it changes -* XML_Feed_Parser has major problems with category and link tags; consider replacing? diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index 5e38a523ea..c755a094e6 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -668,9 +668,27 @@ class Ostatus_profile extends Memcached_DataObject */ protected function purify($html) { - // @fixme disable caching or set a sane temp dir require_once(INSTALLDIR.'/extlib/HTMLPurifier/HTMLPurifier.auto.php'); - $purifier = new HTMLPurifier(); + + // By default Purifier wants to cache data to its own code directories, + // and spews error messages if they're not writable. + $config = HTMLPurifier_Config::createDefault(); + if (common_config('ostatus', 'purify_cache')) { + $config->set('Cache.SerializerPath', common_config('ostatus', 'purify_cache')); + } else { + // Although recommended in the documentation, this produces a notice: + // "Core.DefinitionCache is an alias, preferred directive name is Cache.DefinitionImpl" + // If I then follow *those* directions, I get a warning and it doesn't work: + // "Cannot set undefined directive Core.DefinitionImpl" + // So... lesser of two evils. Suppressing the notice from output, + // though it'll still be seen and logged by StatusNet's error handler. + $old = error_reporting(); + error_reporting($old & ~E_NOTICE); + $config->set('Core.DefinitionCache', null); + error_reporting($old); + } + + $purifier = new HTMLPurifier($config); return $purifier->purify($html); } From b782225ade7ac213222882513d89008902910256 Mon Sep 17 00:00:00 2001 From: Sarven Capadisli Date: Thu, 25 Feb 2010 00:10:36 +0100 Subject: [PATCH 2/6] Revert "Updated jQuery Form Plugin from v2.17 to v2.36" This reverts commit 72037d61436978daa1edbd19d52b7e6fc6ae1fa8. Until some of the XHR notice related bugs are sorted out in Opera and Chromium, reverting back to the previous version. It throws slightly less errors. XHR file attachments is still a bit problematic in Opera 10.10/Ubuntu, Opera 10.10/Windows, and Chrome 4/Ubuntu. But this revert will at least allow regular XHR notices to work okay in Opera and Chromium. Standards suck! --- js/jquery.form.js | 1292 ++++++++++++++++++++++----------------------- 1 file changed, 632 insertions(+), 660 deletions(-) diff --git a/js/jquery.form.js b/js/jquery.form.js index dde394270f..936b847abe 100644 --- a/js/jquery.form.js +++ b/js/jquery.form.js @@ -1,660 +1,632 @@ -/* - * jQuery Form Plugin - * version: 2.36 (07-NOV-2009) - * @requires jQuery v1.2.6 or later - * - * Examples and documentation at: http://malsup.com/jquery/form/ - * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - */ -;(function($) { - -/* - Usage Note: - ----------- - Do not use both ajaxSubmit and ajaxForm on the same form. These - functions are intended to be exclusive. Use ajaxSubmit if you want - to bind your own submit handler to the form. For example, - - $(document).ready(function() { - $('#myForm').bind('submit', function() { - $(this).ajaxSubmit({ - target: '#output' - }); - return false; // <-- important! - }); - }); - - Use ajaxForm when you want the plugin to manage all the event binding - for you. For example, - - $(document).ready(function() { - $('#myForm').ajaxForm({ - target: '#output' - }); - }); - - When using ajaxForm, the ajaxSubmit function will be invoked for you - at the appropriate time. -*/ - -/** - * ajaxSubmit() provides a mechanism for immediately submitting - * an HTML form using AJAX. - */ -$.fn.ajaxSubmit = function(options) { - // fast fail if nothing selected (http://dev.jquery.com/ticket/2752) - if (!this.length) { - log('ajaxSubmit: skipping submit process - no element selected'); - return this; - } - - if (typeof options == 'function') - options = { success: options }; - - var url = $.trim(this.attr('action')); - if (url) { - // clean url (don't include hash vaue) - url = (url.match(/^([^#]+)/)||[])[1]; - } - url = url || window.location.href || ''; - - options = $.extend({ - url: url, - type: this.attr('method') || 'GET', - iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' - }, options || {}); - - // hook for manipulating the form data before it is extracted; - // convenient for use with rich editors like tinyMCE or FCKEditor - var veto = {}; - this.trigger('form-pre-serialize', [this, options, veto]); - if (veto.veto) { - log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); - return this; - } - - // provide opportunity to alter form data before it is serialized - if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { - log('ajaxSubmit: submit aborted via beforeSerialize callback'); - return this; - } - - var a = this.formToArray(options.semantic); - if (options.data) { - options.extraData = options.data; - for (var n in options.data) { - if(options.data[n] instanceof Array) { - for (var k in options.data[n]) - a.push( { name: n, value: options.data[n][k] } ); - } - else - a.push( { name: n, value: options.data[n] } ); - } - } - - // give pre-submit callback an opportunity to abort the submit - if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { - log('ajaxSubmit: submit aborted via beforeSubmit callback'); - return this; - } - - // fire vetoable 'validate' event - this.trigger('form-submit-validate', [a, this, options, veto]); - if (veto.veto) { - log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); - return this; - } - - var q = $.param(a); - - if (options.type.toUpperCase() == 'GET') { - options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; - options.data = null; // data is null for 'get' - } - else - options.data = q; // data is the query string for 'post' - - var $form = this, callbacks = []; - if (options.resetForm) callbacks.push(function() { $form.resetForm(); }); - if (options.clearForm) callbacks.push(function() { $form.clearForm(); }); - - // perform a load on the target only if dataType is not provided - if (!options.dataType && options.target) { - var oldSuccess = options.success || function(){}; - callbacks.push(function(data) { - $(options.target).html(data).each(oldSuccess, arguments); - }); - } - else if (options.success) - callbacks.push(options.success); - - options.success = function(data, status) { - for (var i=0, max=callbacks.length; i < max; i++) - callbacks[i].apply(options, [data, status, $form]); - }; - - // are there files to upload? - var files = $('input:file', this).fieldValue(); - var found = false; - for (var j=0; j < files.length; j++) - if (files[j]) - found = true; - - var multipart = false; -// var mp = 'multipart/form-data'; -// multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); - - // options.iframe allows user to force iframe mode - // 06-NOV-09: now defaulting to iframe mode if file input is detected - if ((files.length && options.iframe !== false) || options.iframe || found || multipart) { - // hack to fix Safari hang (thanks to Tim Molendijk for this) - // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d - if (options.closeKeepAlive) - $.get(options.closeKeepAlive, fileUpload); - else - fileUpload(); - } - else - $.ajax(options); - - // fire 'notify' event - this.trigger('form-submit-notify', [this, options]); - return this; - - - // private function for handling file uploads (hat tip to YAHOO!) - function fileUpload() { - var form = $form[0]; - - if ($(':input[name=submit]', form).length) { - alert('Error: Form elements must not be named "submit".'); - return; - } - - var opts = $.extend({}, $.ajaxSettings, options); - var s = $.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts); - - var id = 'jqFormIO' + (new Date().getTime()); - var $io = $('