aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--CHANGES.txt86
-rw-r--r--COPYRIGHT.txt1
-rw-r--r--actions/admin/site/update_advanced.php6
-rw-r--r--actions/admin/site/update_basic.php2
-rw-r--r--actions/avatar/remove.php52
-rw-r--r--actions/comments/delete.php5
-rw-r--r--actions/friends/collections/add.php2
-rw-r--r--actions/login.php5
-rw-r--r--actions/profile/edit.php9
-rw-r--r--documentation/info/manifest.xml2
-rw-r--r--engine/classes/ElggAccess.php4
-rw-r--r--engine/classes/ElggAttributeLoader.php69
-rw-r--r--engine/classes/ElggAutoP.php24
-rw-r--r--engine/classes/ElggBatch.php68
-rw-r--r--engine/classes/ElggCache.php4
-rw-r--r--engine/classes/ElggData.php2
-rw-r--r--engine/classes/ElggDiskFilestore.php28
-rw-r--r--engine/classes/ElggEntity.php37
-rw-r--r--engine/classes/ElggFile.php9
-rw-r--r--engine/classes/ElggFileCache.php4
-rw-r--r--engine/classes/ElggGroup.php18
-rw-r--r--engine/classes/ElggLRUCache.php181
-rw-r--r--engine/classes/ElggMenuBuilder.php18
-rw-r--r--engine/classes/ElggObject.php19
-rw-r--r--engine/classes/ElggPlugin.php13
-rw-r--r--engine/classes/ElggPluginPackage.php1
-rw-r--r--engine/classes/ElggPriorityList.php13
-rw-r--r--engine/classes/ElggSite.php14
-rw-r--r--engine/classes/ElggStaticVariableCache.php6
-rw-r--r--engine/classes/ElggTranslit.php55
-rw-r--r--engine/classes/ElggUser.php23
-rw-r--r--engine/classes/ElggVolatileMetadataCache.php92
-rw-r--r--engine/classes/ElggWidget.php7
-rw-r--r--engine/classes/ElggXMLElement.php12
-rw-r--r--engine/handlers/cache_handler.php8
-rw-r--r--engine/lib/actions.php76
-rw-r--r--engine/lib/admin.php22
-rw-r--r--engine/lib/annotations.php40
-rw-r--r--engine/lib/cache.php1
-rw-r--r--engine/lib/configuration.php4
-rw-r--r--engine/lib/database.php75
-rw-r--r--engine/lib/deprecated-1.8.php44
-rw-r--r--engine/lib/elgglib.php31
-rw-r--r--engine/lib/entities.php166
-rw-r--r--engine/lib/extender.php18
-rw-r--r--engine/lib/group.php4
-rw-r--r--engine/lib/input.php4
-rw-r--r--engine/lib/languages.php3
-rw-r--r--engine/lib/location.php2
-rw-r--r--engine/lib/metadata.php46
-rw-r--r--engine/lib/metastrings.php21
-rw-r--r--engine/lib/navigation.php9
-rw-r--r--engine/lib/opendd.php4
-rw-r--r--engine/lib/output.php33
-rw-r--r--engine/lib/pageowner.php4
-rw-r--r--engine/lib/plugins.php57
-rw-r--r--engine/lib/relationships.php6
-rw-r--r--engine/lib/river.php16
-rw-r--r--engine/lib/sessions.php3
-rw-r--r--engine/lib/statistics.php10
-rw-r--r--engine/lib/upgrade.php18
-rw-r--r--engine/lib/upgrades/2009102801.php5
-rw-r--r--engine/lib/upgrades/2010033101.php2
-rw-r--r--engine/lib/upgrades/2010061501.php6
-rw-r--r--engine/lib/upgrades/2010071001.php5
-rw-r--r--engine/lib/upgrades/2010071002.php5
-rw-r--r--engine/lib/upgrades/2011052801.php5
-rw-r--r--engine/lib/upgrades/2012041801-1.8.3-multiple_user_tokens-852225f7fd89f6c5.php2
-rw-r--r--engine/lib/upgrades/2013030600-1.8.13-update_user_location-8999eb8bf1bdd9a3.php4
-rw-r--r--engine/lib/upgrades/2013051700-1.8.15-add_missing_group_index-52a63a3a3ffaced2.php28
-rw-r--r--engine/lib/upgrades/2013052900-1.8.15-ipv6_in_syslog-f5c2cc0196e9e731.php12
-rw-r--r--engine/lib/user_settings.php2
-rw-r--r--engine/lib/users.php34
-rw-r--r--engine/lib/views.php48
-rw-r--r--engine/lib/web_services.php19
-rw-r--r--engine/schema/mysql.sql2
-rw-r--r--engine/tests/api/access_collections.php3
-rw-r--r--engine/tests/api/annotations.php80
-rw-r--r--engine/tests/api/entity_getter_functions.php4
-rw-r--r--engine/tests/api/helpers.php103
-rw-r--r--engine/tests/api/metadata.php16
-rw-r--r--engine/tests/api/metadata_cache.php7
-rw-r--r--engine/tests/api/metastrings.php33
-rw-r--r--engine/tests/api/plugins.php4
-rw-r--r--engine/tests/objects/entities.php2
-rw-r--r--engine/tests/objects/objects.php2
-rw-r--r--engine/tests/objects/users.php21
-rw-r--r--engine/tests/regression/trac_bugs.php161
-rw-r--r--engine/tests/test_files/plugin_18/manifest.xml2
-rw-r--r--htaccess_dist8
-rw-r--r--install/ElggInstaller.php2
-rw-r--r--install/cli/sample_installer.php40
-rw-r--r--js/lib/elgglib.js4
-rw-r--r--js/lib/languages.js3
-rw-r--r--js/lib/session.js32
-rw-r--r--js/lib/ui.river.js26
-rw-r--r--js/lib/ui.userpicker.js4
-rw-r--r--js/tests/ElggLibTest.js11
-rw-r--r--js/tests/README5
-rw-r--r--languages/en.php7
-rw-r--r--mod/blog/actions/blog/save.php11
-rw-r--r--mod/blog/start.php15
-rw-r--r--mod/blog/views/default/blog/sidebar/archives.php2
-rw-r--r--mod/blog/views/default/forms/blog/save.php2
-rw-r--r--mod/blog/views/default/river/object/blog/create.php6
-rw-r--r--mod/bookmarks/languages/en.php2
-rw-r--r--mod/bookmarks/pages/bookmarks/all.php3
-rw-r--r--mod/bookmarks/pages/bookmarks/friends.php2
-rw-r--r--mod/bookmarks/pages/bookmarks/owner.php3
-rw-r--r--mod/bookmarks/start.php21
-rw-r--r--mod/developers/languages/en.php3
-rw-r--r--mod/developers/manifest.xml2
-rw-r--r--mod/developers/start.php9
-rw-r--r--mod/developers/views/default/theme_preview/components/image_block.php12
-rw-r--r--mod/developers/views/default/theme_preview/components/list.php38
-rw-r--r--mod/developers/views/default/theme_preview/components/messages.php10
-rw-r--r--mod/developers/views/default/theme_preview/components/table.php22
-rw-r--r--mod/developers/views/default/theme_preview/icons/avatars.php72
-rw-r--r--mod/developers/views/default/theme_preview/icons/sprites.php120
-rw-r--r--mod/developers/views/default/theme_preview/modules/modules.php44
-rw-r--r--mod/developers/views/default/theme_preview/navigation/breadcrumbs.php20
-rw-r--r--mod/developers/views/default/theme_preview/navigation/default.php22
-rw-r--r--mod/developers/views/default/theme_preview/navigation/extras.php34
-rw-r--r--mod/developers/views/default/theme_preview/navigation/filter.php26
-rw-r--r--mod/developers/views/default/theme_preview/navigation/horizontal.php24
-rw-r--r--mod/developers/views/default/theme_preview/navigation/owner_block.php26
-rw-r--r--mod/developers/views/default/theme_preview/navigation/page.php38
-rw-r--r--mod/developers/views/default/theme_preview/navigation/pagination.php14
-rw-r--r--mod/developers/views/default/theme_preview/navigation/site.php36
-rw-r--r--mod/developers/views/default/theme_preview/navigation/tabs.php18
-rw-r--r--mod/developers/views/default/theme_preview/typography/headings.php10
-rw-r--r--mod/developers/views/default/theme_preview/typography/misc.php32
-rw-r--r--mod/developers/views/default/theme_preview/typography/paragraph.php36
-rw-r--r--mod/embed/start.php26
-rw-r--r--mod/externalpages/start.php8
-rw-r--r--mod/file/actions/file/upload.php4
-rw-r--r--mod/file/pages/file/friends.php2
-rw-r--r--mod/file/pages/file/owner.php3
-rw-r--r--mod/file/pages/file/world.php3
-rw-r--r--mod/groups/actions/groups/edit.php24
-rw-r--r--mod/groups/actions/groups/membership/invite.php73
-rw-r--r--mod/groups/lib/discussion.php5
-rw-r--r--mod/groups/lib/groups.php7
-rw-r--r--mod/groups/start.php4
-rw-r--r--mod/groups/views/default/forms/groups/edit.php2
-rw-r--r--mod/groups/views/default/groups/css.php4
-rw-r--r--mod/groups/views/default/groups/profile/summary.php9
-rw-r--r--mod/groups/views/default/groups/sidebar/my_status.php2
-rw-r--r--mod/groups/views/default/object/groupforumtopic.php5
-rw-r--r--mod/htmlawed/start.php4
-rw-r--r--mod/htmlawed/tests/tags.php78
-rw-r--r--mod/logbrowser/views/default/forms/logbrowser/refine.php4
-rw-r--r--mod/logbrowser/views/default/logbrowser/refine.php2
-rw-r--r--mod/logbrowser/views/default/logbrowser/table.php2
-rw-r--r--mod/logrotate/languages/en.php3
-rw-r--r--mod/logrotate/start.php51
-rw-r--r--mod/logrotate/views/default/plugins/logrotate/settings.php1
-rw-r--r--mod/messageboard/pages/messageboard/owner.php1
-rw-r--r--mod/messages/start.php36
-rw-r--r--mod/oauth_api/manifest.xml25
-rw-r--r--mod/oauth_api/start.php24
-rw-r--r--mod/oauth_api/vendors/oauth/LICENSE21
-rw-r--r--mod/oauth_api/vendors/oauth/example/server/INSTALL53
-rw-r--r--mod/oauth_api/vendors/oauth/example/server/core/init.php127
-rw-r--r--mod/oauth_api/vendors/oauth/example/server/core/templates/inc/footer.tpl2
-rw-r--r--mod/oauth_api/vendors/oauth/example/server/core/templates/inc/header.tpl2
-rw-r--r--mod/oauth_api/vendors/oauth/example/server/core/templates/index.tpl13
-rw-r--r--mod/oauth_api/vendors/oauth/example/server/core/templates/logon.tpl21
-rw-r--r--mod/oauth_api/vendors/oauth/example/server/core/templates/register.tpl41
-rw-r--r--mod/oauth_api/vendors/oauth/example/server/www/hello.php65
-rw-r--r--mod/oauth_api/vendors/oauth/example/server/www/index.php37
-rw-r--r--mod/oauth_api/vendors/oauth/example/server/www/logon.php55
-rw-r--r--mod/oauth_api/vendors/oauth/example/server/www/oauth.php77
-rw-r--r--mod/oauth_api/vendors/oauth/example/server/www/register.php28
-rw-r--r--mod/oauth_api/vendors/oauth/example/server/www/services.xrds.php71
-rw-r--r--mod/oauth_api/vendors/oauth/library/OAuthDiscovery.php226
-rw-r--r--mod/oauth_api/vendors/oauth/library/OAuthException.php50
-rw-r--r--mod/oauth_api/vendors/oauth/library/OAuthRequest.php801
-rw-r--r--mod/oauth_api/vendors/oauth/library/OAuthRequestLogger.php274
-rw-r--r--mod/oauth_api/vendors/oauth/library/OAuthRequestSigner.php209
-rw-r--r--mod/oauth_api/vendors/oauth/library/OAuthRequestVerifier.php262
-rw-r--r--mod/oauth_api/vendors/oauth/library/OAuthRequester.php508
-rw-r--r--mod/oauth_api/vendors/oauth/library/OAuthServer.php232
-rw-r--r--mod/oauth_api/vendors/oauth/library/OAuthStore.php86
-rw-r--r--mod/oauth_api/vendors/oauth/library/body/OAuthBodyContentDisposition.php129
-rw-r--r--mod/oauth_api/vendors/oauth/library/body/OAuthBodyMultipartFormdata.php143
-rw-r--r--mod/oauth_api/vendors/oauth/library/discovery/xrds_parse.php304
-rw-r--r--mod/oauth_api/vendors/oauth/library/discovery/xrds_parse.txt101
-rw-r--r--mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod.class.php69
-rw-r--r--mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod_HMAC_SHA1.php115
-rw-r--r--mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod_MD5.php95
-rw-r--r--mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod_PLAINTEXT.php80
-rw-r--r--mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod_RSA_SHA1.php136
-rw-r--r--mod/oauth_api/vendors/oauth/library/store/OAuthStoreAbstract.class.php149
-rw-r--r--mod/oauth_api/vendors/oauth/library/store/OAuthStoreAnyMeta.php265
-rw-r--r--mod/oauth_api/vendors/oauth/library/store/OAuthStoreMySQL.php1879
-rw-r--r--mod/oauth_api/vendors/oauth/library/store/mysql/install.php32
-rw-r--r--mod/oauth_api/vendors/oauth/library/store/mysql/mysql.sql219
-rw-r--r--mod/oauth_api/vendors/oauth/test/discovery/xrds-fireeagle.xrds78
-rw-r--r--mod/oauth_api/vendors/oauth/test/discovery/xrds-getsatisfaction.xrds73
-rw-r--r--mod/oauth_api/vendors/oauth/test/discovery/xrds-magnolia.xrds81
-rw-r--r--mod/oauth_api/vendors/oauth/test/oauth_test.php188
-rw-r--r--mod/pages/actions/annotations/page/delete.php20
-rw-r--r--mod/pages/actions/pages/delete.php26
-rw-r--r--mod/pages/languages/en.php7
-rw-r--r--mod/pages/lib/pages.php7
-rw-r--r--mod/pages/pages/pages/edit.php13
-rw-r--r--mod/pages/pages/pages/friends.php2
-rw-r--r--mod/pages/pages/pages/history.php4
-rw-r--r--mod/pages/pages/pages/owner.php2
-rw-r--r--mod/pages/start.php48
-rw-r--r--mod/pages/upgrades/2012061800.php49
-rw-r--r--mod/pages/views/default/annotation/page.php18
-rw-r--r--mod/pages/views/default/object/page_top.php26
-rw-r--r--mod/pages/views/default/pages/sidebar/history.php1
-rw-r--r--mod/profile/icondirect.php6
-rw-r--r--mod/profile/views/default/profile/details.php16
-rw-r--r--mod/reportedcontent/views/default/object/reported_content.php20
-rw-r--r--mod/search/README.txt2
-rw-r--r--mod/search/search_hooks.php140
-rw-r--r--mod/search/views/default/search/comments/entity.php11
-rw-r--r--mod/search/views/default/search/list.php14
-rw-r--r--mod/search/views/rss/search/comments/entity.php11
-rw-r--r--mod/thewire/pages/thewire/everyone.php2
-rw-r--r--mod/thewire/pages/thewire/friends.php2
-rw-r--r--mod/thewire/pages/thewire/owner.php4
-rw-r--r--mod/tinymce/views/default/js/tinymce.php12
-rw-r--r--mod/twitter/graphics/thewire_speech_bubble.gifbin560 -> 0 bytes
-rw-r--r--mod/twitter/graphics/twitter16px.pngbin724 -> 0 bytes
-rw-r--r--mod/twitter/languages/en.php17
-rw-r--r--mod/twitter/manifest.xml16
-rw-r--r--mod/twitter/start.php14
-rw-r--r--mod/twitter/views/default/twitter/css.php63
-rw-r--r--mod/twitter/views/default/widgets/twitter/content.php42
-rw-r--r--mod/twitter/views/default/widgets/twitter/edit.php24
-rw-r--r--mod/twitter_api/languages/en.php4
-rw-r--r--mod/twitter_api/lib/twitter_api.php41
-rw-r--r--mod/twitter_api/manifest.xml10
-rw-r--r--mod/twitter_api/pages/twitter_api/interstitial.php4
-rw-r--r--mod/twitter_api/start.php33
-rw-r--r--mod/twitter_api/vendors/twitteroauth/OAuth.php390
-rw-r--r--mod/twitter_api/vendors/twitteroauth/README117
-rw-r--r--mod/twitter_api/vendors/twitteroauth/twitterOAuth.php16
-rw-r--r--mod/twitter_api/views/default/forms/twitter_api/interstitial_settings.php7
-rw-r--r--mod/twitter_api/views/default/plugins/twitter_api/settings.php15
-rw-r--r--pages/account/forgotten_password.php11
-rw-r--r--pages/account/login.php14
-rw-r--r--pages/account/register.php11
-rw-r--r--pages/account/reset_password.php11
-rw-r--r--pages/avatar/edit.php5
-rw-r--r--pages/river.php1
-rw-r--r--upgrade.php2
-rw-r--r--version.php4
-rw-r--r--views/default/css/admin.php5
-rw-r--r--views/default/css/elements/navigation.php7
-rw-r--r--views/default/css/ie.php8
-rw-r--r--views/default/css/ie7.php1
-rw-r--r--views/default/forms/plugins/settings/save.php6
-rw-r--r--views/default/forms/profile/edit.php13
-rw-r--r--views/default/icon/default.php30
-rw-r--r--views/default/input/userpicker.php8
-rw-r--r--views/default/js/elgg.php2
-rw-r--r--views/default/js/languages.php24
-rw-r--r--views/default/js/walled_garden.php28
-rw-r--r--views/default/object/default.php1
-rw-r--r--views/default/object/elements/full.php4
-rw-r--r--views/default/object/elements/summary.php2
-rw-r--r--views/default/output/access.php2
-rw-r--r--views/default/output/tag.php16
-rw-r--r--views/default/output/tags.php20
-rw-r--r--views/default/page/walled_garden.php15
-rw-r--r--views/default/river/elements/summary.php3
273 files changed, 3468 insertions, 8984 deletions
diff --git a/.gitignore b/.gitignore
index c0bba2c6c..a1c78c400 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,7 +38,7 @@
!/mod/uservalidationbyemail/
!/mod/zaudio/
-# ignore IDE/hidden/OS cache files
+# ignore IDE/hidden/testing/OS cache files
.*
*~
/nbproject
@@ -49,6 +49,7 @@ Session.vim
tmtags
Thumbs.db
Desktop.ini
+/JsTestDriver-*.jar
# don't ignore travis config
!/.travis.yml
diff --git a/CHANGES.txt b/CHANGES.txt
index fd9d0eef6..187dc7e25 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,14 +1,94 @@
+Version 1.8.16
+(June 25, 2013 from https://github.com/Elgg/Elgg/tree/1.8)
+ Contributing Developers:
+ * Brett Profitt
+ * Cash Costello
+ * Jeff Tilson
+ * Jerome Bakker
+ * Paweł Sroka
+ * Steve Clay
+
+ Security Fixes:
+ * Fixed avatar removal bug (thanks to Jerome Bakker for the first report of this)
+
+ Bugfixes:
+ * Fixed infinite loop when deleting/disabling an entity with > 50 annotations
+ * Fixed deleting log tables in log rotate plugin
+ * Added full text index for groups if missing
+ * Added workaround for IE8 and jumping user avatar
+ * Fixed pagination for members pages
+ * Fixed several internal cache issues
+ * Plus many more bug fixes
+
+
+Version 1.8.15
+(April 23, 2013 from https://github.com/Elgg/Elgg/tree/1.8)
+ Contributing Developers:
+ * Cash Costello
+ * Ismayil Khayredinov
+ * Jeff Tilson
+ * Juho Jaakkola
+ * Matt Beckett
+ * Paweł Sroka
+ * Sem
+ * Steve Clay
+ * Tom Voorneveld
+
+ Bugfixes:
+ * Not displaying http:// on profiles when website isn't set
+ * Fixed pagination display issue for small screens
+ * Not hiding subpages of top level pages that have been deleted
+ * Stop corrupting JavaScript views with elgg deprecation messages
+ * Fixed out of memory error due to query cache
+ * Fixed bug preventing users authorizing Twitter account access
+ * Fixed friends access level for editing pages
+ * Fixed uploading files within the embed dialog
+
+ Enhancements:
+ * Added browser caching of language JS files
+ * Adding nofollow on user posted URLs for spam deterrence (thanks to Hellekin)
+ * Auto-registering views for simplecache when their URL is requested
+ * Display helpful message for those who have site URL configuration issues
+ * Can revert to a previous revision with pages plugin
+ * Site owners can turn off posting wire messages to Twitter
+ * Search results are sorted by relevance
+
+ Dropped Plugins:
+ * Twitter widget due to changes in Twitter API and terms of service
+ * OAuth API plugin due to conflicts with the Twitter API plugin
+
+
Version 1.8.14
-(X xx, 2013 from https://github.com/Elgg/Elgg/tree/1.8)
+(March 12, 2013 from https://github.com/Elgg/Elgg/tree/1.8)
Contributing Developers:
+ * Aday Talavera
+ * Brett Profitt
+ * Cash Costello
+ * Ed Lyons
+ * German Bortoli
+ * Hellekin Wolf
+ * iionly
+ * Jerome Bakker
* Luciano Lima
+ * Matt Beckett
* Paweł Sroka
+ * Sem
+ * Steve Clay
+
+ Security Fixes:
+ * Fixed a XSS vulnerability when accepting URLs on user profiles
+ * Fixed bug that exposed subject lines of messages in inbox
+ * Added requirement for CSRF token for login
Bugfixes:
- *
+ * Strip html tags from tag input
+ * Fixed several display issues for IE7
+ * Fixed several issues with blog drafts
+ * Fixed repeated token timeout errors
+ * Fixed JavaScript localization for non-English languages
Enhancements:
- * Web services fall back to xml if the viewtype is invalid
+ * Web services fall back to json if the viewtype is invalid
Version 1.8.13
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt
index 76781f25a..262515386 100644
--- a/COPYRIGHT.txt
+++ b/COPYRIGHT.txt
@@ -6,6 +6,7 @@ The MITRE Corportation (jricher@mitre.org)
Curverider Ltd (info@elgg.com)
Individuals:
+Steve Clay (steve@mrclay.org)
Cash Costello (cash.costello@gmail.com)
Brett Profitt (brett.profitt@gmail.com)
Dave Tosh (davidgtosh@gmail.com)
diff --git a/actions/admin/site/update_advanced.php b/actions/admin/site/update_advanced.php
index 0fd8d1f35..4888b0a8d 100644
--- a/actions/admin/site/update_advanced.php
+++ b/actions/admin/site/update_advanced.php
@@ -14,10 +14,10 @@ if ($site = elgg_get_site_entity()) {
throw new InstallationException(elgg_echo('InvalidParameterException:NonElggSite'));
}
- $site->url = get_input('wwwroot');
+ $site->url = rtrim(get_input('wwwroot', '', false), '/') . '/';
- datalist_set('path', sanitise_filepath(get_input('path')));
- $dataroot = sanitise_filepath(get_input('dataroot'));
+ datalist_set('path', sanitise_filepath(get_input('path', '', false)));
+ $dataroot = sanitise_filepath(get_input('dataroot', '', false));
// check for relative paths
if (stripos(PHP_OS, 'win') === 0) {
diff --git a/actions/admin/site/update_basic.php b/actions/admin/site/update_basic.php
index 97d258b65..9765182cc 100644
--- a/actions/admin/site/update_basic.php
+++ b/actions/admin/site/update_basic.php
@@ -16,7 +16,7 @@ if ($site = elgg_get_site_entity()) {
}
$site->description = get_input('sitedescription');
- $site->name = get_input('sitename');
+ $site->name = strip_tags(get_input('sitename'));
$site->email = get_input('siteemail');
$site->save();
diff --git a/actions/avatar/remove.php b/actions/avatar/remove.php
index cd38e456a..9cb40a760 100644
--- a/actions/avatar/remove.php
+++ b/actions/avatar/remove.php
@@ -3,32 +3,34 @@
* Avatar remove action
*/
-$guid = get_input('guid');
-$user = get_entity($guid);
-if ($user) {
- // Delete all icons from diskspace
- $icon_sizes = elgg_get_config('icon_sizes');
- foreach ($icon_sizes as $name => $size_info) {
- $file = new ElggFile();
- $file->owner_guid = $guid;
- $file->setFilename("profile/{$guid}{$name}.jpg");
- $filepath = $file->getFilenameOnFilestore();
- if (!$file->delete()) {
- elgg_log("Avatar file remove failed. Remove $filepath manually, please.", 'WARNING');
- }
- }
-
- // Remove crop coords
- unset($user->x1);
- unset($user->x2);
- unset($user->y1);
- unset($user->y2);
-
- // Remove icon
- unset($user->icontime);
- system_message(elgg_echo('avatar:remove:success'));
-} else {
+$user_guid = get_input('guid');
+$user = get_user($user_guid);
+
+if (!$user || !$user->canEdit()) {
register_error(elgg_echo('avatar:remove:fail'));
+ forward(REFERER);
}
+// Delete all icons from diskspace
+$icon_sizes = elgg_get_config('icon_sizes');
+foreach ($icon_sizes as $name => $size_info) {
+ $file = new ElggFile();
+ $file->owner_guid = $user_guid;
+ $file->setFilename("profile/{$user_guid}{$name}.jpg");
+ $filepath = $file->getFilenameOnFilestore();
+ if (!$file->delete()) {
+ elgg_log("Avatar file remove failed. Remove $filepath manually, please.", 'WARNING');
+ }
+}
+
+// Remove crop coords
+unset($user->x1);
+unset($user->x2);
+unset($user->y1);
+unset($user->y2);
+
+// Remove icon
+unset($user->icontime);
+
+system_message(elgg_echo('avatar:remove:success'));
forward(REFERER);
diff --git a/actions/comments/delete.php b/actions/comments/delete.php
index f2c058ff4..c6b481da4 100644
--- a/actions/comments/delete.php
+++ b/actions/comments/delete.php
@@ -5,11 +5,6 @@
* @package Elgg
*/
-// Ensure we're logged in
-if (!elgg_is_logged_in()) {
- forward();
-}
-
// Make sure we can get the comment in question
$annotation_id = (int) get_input('annotation_id');
$comment = elgg_get_annotation_from_id($annotation_id);
diff --git a/actions/friends/collections/add.php b/actions/friends/collections/add.php
index 9dc17b37e..e63a149f7 100644
--- a/actions/friends/collections/add.php
+++ b/actions/friends/collections/add.php
@@ -6,7 +6,7 @@
* @subpackage Friends.Collections
*/
-$collection_name = get_input('collection_name');
+$collection_name = htmlspecialchars(get_input('collection_name', '', false), ENT_QUOTES, 'UTF-8');
$friends = get_input('friends_collection');
if (!$collection_name) {
diff --git a/actions/login.php b/actions/login.php
index 1e5e92ede..bd7f91299 100644
--- a/actions/login.php
+++ b/actions/login.php
@@ -9,7 +9,6 @@
// set forward url
if (!empty($_SESSION['last_forward_from'])) {
$forward_url = $_SESSION['last_forward_from'];
- unset($_SESSION['last_forward_from']);
} elseif (get_input('returntoreferer')) {
$forward_url = REFERER;
} else {
@@ -62,5 +61,9 @@ if ($user->language) {
$message = elgg_echo('loginok');
}
+if (isset($_SESSION['last_forward_from'])) {
+ unset($_SESSION['last_forward_from']);
+}
+
system_message($message);
forward($forward_url);
diff --git a/actions/profile/edit.php b/actions/profile/edit.php
index 89bf2bc0b..e1f066e82 100644
--- a/actions/profile/edit.php
+++ b/actions/profile/edit.php
@@ -4,6 +4,8 @@
*
*/
+elgg_make_sticky_form('profile:edit');
+
$guid = get_input('guid');
$owner = get_entity($guid);
@@ -48,6 +50,10 @@ foreach ($profile_fields as $shortname => $valuetype) {
forward(REFERER);
}
+ if ($value && $valuetype == 'url' && !preg_match('~^https?\://~i', $value)) {
+ $value = "http://$value";
+ }
+
if ($valuetype == 'tags') {
$value = string_to_tag_array($value);
}
@@ -76,7 +82,7 @@ if (sizeof($input) > 0) {
);
elgg_delete_metadata($options);
- if(!is_null($value) && ($value !== '')){
+ if (!is_null($value) && ($value !== '')) {
// only create metadata for non empty values (0 is allowed) to prevent metadata records with empty string values #4858
if (isset($accesslevel[$shortname])) {
@@ -103,6 +109,7 @@ if (sizeof($input) > 0) {
// Notify of profile update
elgg_trigger_event('profileupdate', $owner->type, $owner);
+ elgg_clear_sticky_form('profile:edit');
system_message(elgg_echo("profile:saved"));
}
diff --git a/documentation/info/manifest.xml b/documentation/info/manifest.xml
index 494158481..4fd4be8ce 100644
--- a/documentation/info/manifest.xml
+++ b/documentation/info/manifest.xml
@@ -7,7 +7,7 @@
<description>This is a longer, more interesting description of my plugin, its features, and other important information.</description>
<website>http://www.elgg.org/</website>
<repository>https://github.com/Elgg/Elgg</repository>
- <bugtracker>http://trac.elgg.org</bugtracker>
+ <bugtracker>https://github.com/Elgg/Elgg/issues</bugtracker>
<donations>http://elgg.org/supporter.php</donations>
<copyright>(C) Elgg 2011</copyright>
<license>GNU General Public License version 2</license>
diff --git a/engine/classes/ElggAccess.php b/engine/classes/ElggAccess.php
index 6f8d9bb4b..0aed477fc 100644
--- a/engine/classes/ElggAccess.php
+++ b/engine/classes/ElggAccess.php
@@ -16,6 +16,7 @@ class ElggAccess {
*/
private $ignore_access;
+ // @codingStandardsIgnoreStart
/**
* Get current ignore access setting.
*
@@ -26,6 +27,7 @@ class ElggAccess {
elgg_deprecated_notice('ElggAccess::get_ignore_access() is deprecated by ElggAccess::getIgnoreAccess()', 1.8);
return $this->getIgnoreAccess();
}
+ // @codingStandardsIgnoreEnd
/**
* Get current ignore access setting.
@@ -36,6 +38,7 @@ class ElggAccess {
return $this->ignore_access;
}
+ // @codingStandardsIgnoreStart
/**
* Set ignore access.
*
@@ -49,6 +52,7 @@ class ElggAccess {
elgg_deprecated_notice('ElggAccess::set_ignore_access() is deprecated by ElggAccess::setIgnoreAccess()', 1.8);
return $this->setIgnoreAccess($ignore);
}
+ // @codingStandardsIgnoreEnd
/**
* Set ignore access.
diff --git a/engine/classes/ElggAttributeLoader.php b/engine/classes/ElggAttributeLoader.php
index 2d1c1abde..ffc80b02d 100644
--- a/engine/classes/ElggAttributeLoader.php
+++ b/engine/classes/ElggAttributeLoader.php
@@ -4,6 +4,9 @@
* Loads ElggEntity attributes from DB or validates those passed in via constructor
*
* @access private
+ *
+ * @package Elgg.Core
+ * @subpackage DataModel
*/
class ElggAttributeLoader {
@@ -21,7 +24,7 @@ class ElggAttributeLoader {
'time_created',
'time_updated',
'last_action',
- 'enabled'
+ 'enabled',
);
/**
@@ -65,9 +68,11 @@ class ElggAttributeLoader {
public $full_loader = '';
/**
- * @param string $class class of object being loaded
- * @param string $required_type entity type this is being used to populate
- * @param array $initialized_attrs attributes after initializeAttributes() has been run
+ * Constructor
+ *
+ * @param string $class class of object being loaded
+ * @param string $required_type entity type this is being used to populate
+ * @param array $initialized_attrs attributes after initializeAttributes() has been run
* @throws InvalidArgumentException
*/
public function __construct($class, $required_type, array $initialized_attrs) {
@@ -87,14 +92,33 @@ class ElggAttributeLoader {
$this->secondary_attr_names = array_diff($all_attr_names, self::$primary_attr_names);
}
+ /**
+ * Get primary attributes missing that are missing
+ *
+ * @param stdClass $row Database row
+ * @return array
+ */
protected function isMissingPrimaries($row) {
return array_diff(self::$primary_attr_names, array_keys($row)) !== array();
}
+ /**
+ * Get secondary attributes that are missing
+ *
+ * @param stdClass $row Database row
+ * @return array
+ */
protected function isMissingSecondaries($row) {
return array_diff($this->secondary_attr_names, array_keys($row)) !== array();
}
+ /**
+ * Check that the type is correct
+ *
+ * @param stdClass $row Database row
+ * @return void
+ * @throws InvalidClassException
+ */
protected function checkType($row) {
if ($row['type'] !== $this->required_type) {
$msg = elgg_echo('InvalidClassException:NotValidElggStar', array($row['guid'], $this->class));
@@ -176,6 +200,8 @@ class ElggAttributeLoader {
// saved, these are stored w/ type "site", but with no sites_entity row. These
// are probably only created in the unit tests.
// @todo Don't save vanilla ElggEntities with type "site"
+
+ $row = $this->filterAddedColumns($row);
$row['guid'] = (int) $row['guid'];
return $row;
}
@@ -185,15 +211,38 @@ class ElggAttributeLoader {
}
}
- // loading complete: re-check missing and check type
- if (($was_missing_primaries && $this->isMissingPrimaries($row))
- || ($was_missing_secondaries && $this->isMissingSecondaries($row))) {
- throw new LogicException('Attribute loaders failed to return proper attributes');
- }
+ $row = $this->filterAddedColumns($row);
+
+ // Note: If there are still missing attributes, we're running on a 1.7 or earlier schema. We let
+ // this pass so the upgrades can run.
- // guid needs to be an int http://trac.elgg.org/ticket/4111
+ // guid needs to be an int https://github.com/elgg/elgg/issues/4111
$row['guid'] = (int) $row['guid'];
return $row;
}
+
+ /**
+ * Filter out keys returned by the query which should not appear in the entity's attributes
+ *
+ * @param array $row All columns from the query
+ * @return array Columns acceptable for the entity's attributes
+ */
+ protected function filterAddedColumns($row) {
+ // make an array with keys as acceptable attribute names
+ $acceptable_attrs = self::$primary_attr_names;
+ array_splice($acceptable_attrs, count($acceptable_attrs), 0, $this->secondary_attr_names);
+ $acceptable_attrs = array_combine($acceptable_attrs, $acceptable_attrs);
+
+ // @todo remove these when #4584 is in place
+ $acceptable_attrs['tables_split'] = true;
+ $acceptable_attrs['tables_loaded'] = true;
+
+ foreach ($row as $key => $val) {
+ if (!isset($acceptable_attrs[$key])) {
+ unset($row[$key]);
+ }
+ }
+ return $row;
+ }
}
diff --git a/engine/classes/ElggAutoP.php b/engine/classes/ElggAutoP.php
index f3c7cc972..71536c433 100644
--- a/engine/classes/ElggAutoP.php
+++ b/engine/classes/ElggAutoP.php
@@ -7,6 +7,9 @@
*
* In DIV elements, Ps are only added when there would be at
* least two of them.
+ *
+ * @package Elgg.Core
+ * @subpackage Output
*/
class ElggAutoP {
@@ -51,8 +54,12 @@ class ElggAutoP {
protected $_alterList = 'article aside blockquote body details div footer header
section';
+ /** @var string */
protected $_unique = '';
+ /**
+ * Constructor
+ */
public function __construct() {
$this->_blocks = preg_split('@\\s+@', $this->_blocks);
$this->_descendList = preg_split('@\\s+@', $this->_descendList);
@@ -98,7 +105,7 @@ class ElggAutoP {
$html = str_replace('&', $this->_unique . 'AMP', $html);
$this->_doc = new DOMDocument();
-
+
// parse to DOM, suppressing loadHTML warnings
// http://www.php.net/manual/en/domdocument.loadhtml.php#95463
libxml_use_internal_errors(true);
@@ -112,7 +119,7 @@ class ElggAutoP {
$this->_xpath = new DOMXPath($this->_doc);
// start processing recursively at the BODY element
$nodeList = $this->_xpath->query('//body[1]');
- $this->_addParagraphs($nodeList->item(0));
+ $this->addParagraphs($nodeList->item(0));
// serialize back to HTML
$html = $this->_doc->saveHTML();
@@ -187,15 +194,16 @@ class ElggAutoP {
/**
* Add P and BR elements as necessary
*
- * @param DOMElement $el
+ * @param DOMElement $el DOM element
+ * @return void
*/
- protected function _addParagraphs(DOMElement $el) {
+ protected function addParagraphs(DOMElement $el) {
// no need to call recursively, just queue up
$elsToProcess = array($el);
$inlinesToProcess = array();
while ($el = array_shift($elsToProcess)) {
// if true, we can alter all child nodes, if not, we'll just call
- // _addParagraphs on each element in the descendInto list
+ // addParagraphs on each element in the descendInto list
$alterInline = in_array($el->nodeName, $this->_alterList);
// inside affected elements, we want to trim leading whitespace from
@@ -229,8 +237,8 @@ class ElggAutoP {
if ($alterInline) {
$isText = ($node->nodeType === XML_TEXT_NODE);
$isLastInline = (! $node->nextSibling
- || ($node->nextSibling->nodeType === XML_ELEMENT_NODE
- && in_array($node->nextSibling->nodeName, $this->_blocks)));
+ || ($node->nextSibling->nodeType === XML_ELEMENT_NODE
+ && in_array($node->nextSibling->nodeName, $this->_blocks)));
if ($isElement) {
$isFollowingBr = ($node->nodeName === 'br');
}
@@ -263,7 +271,7 @@ class ElggAutoP {
if ($isBlock) {
if (in_array($node->nodeName, $this->_descendList)) {
$elsToProcess[] = $node;
- //$this->_addParagraphs($node);
+ //$this->addParagraphs($node);
}
}
$openP = true;
diff --git a/engine/classes/ElggBatch.php b/engine/classes/ElggBatch.php
index 5d59425d0..d810ea066 100644
--- a/engine/classes/ElggBatch.php
+++ b/engine/classes/ElggBatch.php
@@ -150,6 +150,20 @@ class ElggBatch
private $incrementOffset = true;
/**
+ * Entities that could not be instantiated during a fetch
+ *
+ * @var stdClass[]
+ */
+ private $incompleteEntities = array();
+
+ /**
+ * Total number of incomplete entities fetched
+ *
+ * @var int
+ */
+ private $totalIncompletes = 0;
+
+ /**
* Batches operations on any elgg_get_*() or compatible function that supports
* an options array.
*
@@ -222,16 +236,22 @@ class ElggBatch
}
/**
+ * Tell the process that an entity was incomplete during a fetch
+ *
+ * @param stdClass $row
+ *
+ * @access private
+ */
+ public function reportIncompleteEntity(stdClass $row) {
+ $this->incompleteEntities[] = $row;
+ }
+
+ /**
* Fetches the next chunk of results
*
* @return bool
*/
private function getNextResultsChunk() {
- // reset memory caches after first chunk load
- if ($this->chunkIndex > 0) {
- global $DB_QUERY_CACHE, $ENTITY_CACHE;
- $DB_QUERY_CACHE = $ENTITY_CACHE = array();
- }
// always reset results.
$this->results = array();
@@ -265,27 +285,47 @@ class ElggBatch
if ($this->incrementOffset) {
$offset = $this->offset + $this->retrievedResults;
} else {
- $offset = $this->offset;
+ $offset = $this->offset + $this->totalIncompletes;
}
$current_options = array(
'limit' => $limit,
- 'offset' => $offset
+ 'offset' => $offset,
+ '__ElggBatch' => $this,
);
$options = array_merge($this->options, $current_options);
- $getter = $this->getter;
- if (is_string($getter)) {
- $this->results = $getter($options);
- } else {
- $this->results = call_user_func_array($getter, array($options));
+ $this->incompleteEntities = array();
+ $this->results = call_user_func_array($this->getter, array($options));
+
+ $num_results = count($this->results);
+ $num_incomplete = count($this->incompleteEntities);
+
+ $this->totalIncompletes += $num_incomplete;
+
+ if ($this->incompleteEntities) {
+ // pad the front of the results with nulls representing the incompletes
+ array_splice($this->results, 0, 0, array_pad(array(), $num_incomplete, null));
+ // ...and skip past them
+ reset($this->results);
+ for ($i = 0; $i < $num_incomplete; $i++) {
+ next($this->results);
+ }
}
if ($this->results) {
$this->chunkIndex++;
- $this->resultIndex = 0;
- $this->retrievedResults += count($this->results);
+
+ // let the system know we've jumped past the nulls
+ $this->resultIndex = $num_incomplete;
+
+ $this->retrievedResults += ($num_results + $num_incomplete);
+ if ($num_results == 0) {
+ // This fetch was *all* incompletes! We need to fetch until we can either
+ // offer at least one row to iterate over, or give up.
+ return $this->getNextResultsChunk();
+ }
return true;
} else {
return false;
diff --git a/engine/classes/ElggCache.php b/engine/classes/ElggCache.php
index 4317f4be9..909eab39b 100644
--- a/engine/classes/ElggCache.php
+++ b/engine/classes/ElggCache.php
@@ -21,6 +21,7 @@ abstract class ElggCache implements ArrayAccess {
$this->variables = array();
}
+ // @codingStandardsIgnoreStart
/**
* Set a cache variable.
*
@@ -35,6 +36,7 @@ abstract class ElggCache implements ArrayAccess {
elgg_deprecated_notice('ElggCache::set_variable() is deprecated by ElggCache::setVariable()', 1.8);
$this->setVariable($variable, $value);
}
+ // @codingStandardsIgnoreEnd
/**
* Set a cache variable.
@@ -52,6 +54,7 @@ abstract class ElggCache implements ArrayAccess {
$this->variables[$variable] = $value;
}
+ // @codingStandardsIgnoreStart
/**
* Get variables for this cache.
*
@@ -65,6 +68,7 @@ abstract class ElggCache implements ArrayAccess {
elgg_deprecated_notice('ElggCache::get_variable() is deprecated by ElggCache::getVariable()', 1.8);
return $this->getVariable($variable);
}
+ // @codingStandardsIgnoreEnd
/**
* Get variables for this cache.
diff --git a/engine/classes/ElggData.php b/engine/classes/ElggData.php
index 426248ca3..4f843cde4 100644
--- a/engine/classes/ElggData.php
+++ b/engine/classes/ElggData.php
@@ -26,6 +26,7 @@ abstract class ElggData implements
*/
protected $attributes = array();
+ // @codingStandardsIgnoreStart
/**
* Initialise the attributes array.
*
@@ -44,6 +45,7 @@ abstract class ElggData implements
elgg_deprecated_notice('initialise_attributes() is deprecated by initializeAttributes()', 1.8);
}
}
+ // @codingStandardsIgnoreEnd
/**
* Initialize the attributes array.
diff --git a/engine/classes/ElggDiskFilestore.php b/engine/classes/ElggDiskFilestore.php
index 7374aad35..6e2354012 100644
--- a/engine/classes/ElggDiskFilestore.php
+++ b/engine/classes/ElggDiskFilestore.php
@@ -194,7 +194,9 @@ class ElggDiskFilestore extends ElggFilestore {
}
/**
- * Returns the filename as saved on disk for an ElggFile object
+ * Get the filename as saved on disk for an ElggFile object
+ *
+ * Returns an empty string if no filename set
*
* @param ElggFile $file File object
*
@@ -213,7 +215,12 @@ class ElggDiskFilestore extends ElggFilestore {
throw new InvalidParameterException($msg);
}
- return $this->dir_root . $this->makefileMatrix($owner_guid) . $file->getFilename();
+ $filename = $file->getFilename();
+ if (!$filename) {
+ return '';
+ }
+
+ return $this->dir_root . $this->makeFileMatrix($owner_guid) . $filename;
}
/**
@@ -221,7 +228,7 @@ class ElggDiskFilestore extends ElggFilestore {
*
* @param ElggFile $file File object
*
- * @return mixed
+ * @return string
*/
public function grabFile(ElggFile $file) {
return file_get_contents($file->getFilenameOnFilestore());
@@ -235,6 +242,9 @@ class ElggDiskFilestore extends ElggFilestore {
* @return bool
*/
public function exists(ElggFile $file) {
+ if (!$file->getFilename()) {
+ return false;
+ }
return file_exists($this->getFilenameOnFilestore($file));
}
@@ -248,12 +258,13 @@ class ElggDiskFilestore extends ElggFilestore {
*/
public function getSize($prefix = '', $container_guid) {
if ($container_guid) {
- return get_dir_size($this->dir_root . $this->makefileMatrix($container_guid) . $prefix);
+ return get_dir_size($this->dir_root . $this->makeFileMatrix($container_guid) . $prefix);
} else {
return false;
}
}
+ // @codingStandardsIgnoreStart
/**
* Create a directory $dirroot
*
@@ -268,6 +279,7 @@ class ElggDiskFilestore extends ElggFilestore {
return $this->makeDirectoryRoot($dirroot);
}
+ // @codingStandardsIgnoreEnd
/**
* Create a directory $dirroot
@@ -287,6 +299,7 @@ class ElggDiskFilestore extends ElggFilestore {
return true;
}
+ // @codingStandardsIgnoreStart
/**
* Multibyte string tokeniser.
*
@@ -318,7 +331,9 @@ class ElggDiskFilestore extends ElggFilestore {
return str_split($string);
}
}
+ // @codingStandardsIgnoreEnd
+ // @codingStandardsIgnoreStart
/**
* Construct a file path matrix for an entity.
*
@@ -330,8 +345,9 @@ class ElggDiskFilestore extends ElggFilestore {
protected function make_file_matrix($identifier) {
elgg_deprecated_notice('ElggDiskFilestore::make_file_matrix() is deprecated by ::makeFileMatrix()', 1.8);
- return $this->makefileMatrix($identifier);
+ return $this->makeFileMatrix($identifier);
}
+ // @codingStandardsIgnoreEnd
/**
* Construct a file path matrix for an entity.
@@ -352,6 +368,7 @@ class ElggDiskFilestore extends ElggFilestore {
return "$time_created/$entity->guid/";
}
+ // @codingStandardsIgnoreStart
/**
* Construct a filename matrix.
*
@@ -370,6 +387,7 @@ class ElggDiskFilestore extends ElggFilestore {
return $this->makeFileMatrix($guid);
}
+ // @codingStandardsIgnoreEnd
/**
* Returns a list of attributes to save to the database when saving
diff --git a/engine/classes/ElggEntity.php b/engine/classes/ElggEntity.php
index f44e73023..a563f6fad 100644
--- a/engine/classes/ElggEntity.php
+++ b/engine/classes/ElggEntity.php
@@ -24,7 +24,7 @@
*
* @package Elgg.Core
* @subpackage DataModel.Entities
- *
+ *
* @property string $type object, user, group, or site (read-only after save)
* @property string $subtype Further clarifies the nature of the entity (read-only after save)
* @property int $guid The unique identifier for this entity (read only)
@@ -352,8 +352,8 @@ abstract class ElggEntity extends ElggData implements
'limit' => 0
);
// @todo in 1.9 make this return false if can't add metadata
- // http://trac.elgg.org/ticket/4520
- //
+ // https://github.com/elgg/elgg/issues/4520
+ //
// need to remove access restrictions right now to delete
// because this is the expected behavior
$ia = elgg_set_ignore_access(true);
@@ -375,12 +375,11 @@ abstract class ElggEntity extends ElggData implements
}
return $result;
- }
-
- // unsaved entity. store in temp array
- // returning single entries instead of an array of 1 element is decided in
- // getMetaData(), just like pulling from the db.
- else {
+ } else {
+ // unsaved entity. store in temp array
+ // returning single entries instead of an array of 1 element is decided in
+ // getMetaData(), just like pulling from the db.
+ //
// if overwrite, delete first
if (!$multiple || !isset($this->temp_metadata[$name])) {
$this->temp_metadata[$name] = array();
@@ -965,7 +964,7 @@ abstract class ElggEntity extends ElggData implements
*
* @tip Can be overridden by registering for the permissions_check:comment,
* <entity type> plugin hook.
- *
+ *
* @param int $user_guid User guid (default is logged in user)
*
* @return bool
@@ -1271,15 +1270,23 @@ abstract class ElggEntity extends ElggData implements
public function save() {
$guid = $this->getGUID();
if ($guid > 0) {
- cache_entity($this);
- return update_entity(
+ // See #5600. This ensures the lower level can_edit_entity() check will use a
+ // fresh entity from the DB so it sees the persisted owner_guid
+ _elgg_disable_caching_for_entity($guid);
+
+ $ret = update_entity(
$guid,
$this->get('owner_guid'),
$this->get('access_id'),
$this->get('container_guid'),
$this->get('time_created')
);
+
+ _elgg_enable_caching_for_entity($guid);
+ _elgg_cache_entity($this);
+
+ return $ret;
} else {
// Create a new entity (nb: using attribute array directly
// 'cos set function does something special!)
@@ -1321,7 +1328,7 @@ abstract class ElggEntity extends ElggData implements
$this->attributes['subtype'] = get_subtype_id($this->attributes['type'],
$this->attributes['subtype']);
- cache_entity($this);
+ _elgg_cache_entity($this);
return $this->attributes['guid'];
}
@@ -1358,12 +1365,12 @@ abstract class ElggEntity extends ElggData implements
$this->attributes['tables_loaded']++;
}
- // guid needs to be an int http://trac.elgg.org/ticket/4111
+ // guid needs to be an int https://github.com/elgg/elgg/issues/4111
$this->attributes['guid'] = (int)$this->attributes['guid'];
// Cache object handle
if ($this->attributes['guid']) {
- cache_entity($this);
+ _elgg_cache_entity($this);
}
return true;
diff --git a/engine/classes/ElggFile.php b/engine/classes/ElggFile.php
index 3e9c24c17..23080834b 100644
--- a/engine/classes/ElggFile.php
+++ b/engine/classes/ElggFile.php
@@ -275,9 +275,14 @@ class ElggFile extends ElggObject {
*/
public function delete() {
$fs = $this->getFilestore();
- if ($fs->delete($this)) {
- return parent::delete();
+
+ $result = $fs->delete($this);
+
+ if ($this->getGUID() && $result) {
+ $result = parent::delete();
}
+
+ return $result;
}
/**
diff --git a/engine/classes/ElggFileCache.php b/engine/classes/ElggFileCache.php
index e654f1db2..94143f777 100644
--- a/engine/classes/ElggFileCache.php
+++ b/engine/classes/ElggFileCache.php
@@ -26,6 +26,7 @@ class ElggFileCache extends ElggCache {
}
}
+ // @codingStandardsIgnoreStart
/**
* Create and return a handle to a file.
*
@@ -41,6 +42,7 @@ class ElggFileCache extends ElggCache {
return $this->createFile($filename, $rw);
}
+ // @codingStandardsIgnoreEnd
/**
* Create and return a handle to a file.
@@ -72,6 +74,7 @@ class ElggFileCache extends ElggCache {
return fopen($path . $filename, $rw);
}
+ // @codingStandardsIgnoreStart
/**
* Create a sanitised filename for the file.
*
@@ -86,6 +89,7 @@ class ElggFileCache extends ElggCache {
return $filename;
}
+ // @codingStandardsIgnoreEnd
/**
* Create a sanitised filename for the file.
diff --git a/engine/classes/ElggGroup.php b/engine/classes/ElggGroup.php
index 61f699f1a..7e69b7a84 100644
--- a/engine/classes/ElggGroup.php
+++ b/engine/classes/ElggGroup.php
@@ -48,21 +48,18 @@ class ElggGroup extends ElggEntity
$msg = elgg_echo('IOException:FailedToLoadGUID', array(get_class(), $guid->guid));
throw new IOException($msg);
}
-
- // Is $guid is an ElggGroup? Use a copy constructor
} else if ($guid instanceof ElggGroup) {
+ // $guid is an ElggGroup so this is a copy constructor
elgg_deprecated_notice('This type of usage of the ElggGroup constructor was deprecated. Please use the clone method.', 1.7);
foreach ($guid->attributes as $key => $value) {
$this->attributes[$key] = $value;
}
-
- // Is this is an ElggEntity but not an ElggGroup = ERROR!
} else if ($guid instanceof ElggEntity) {
+ // @todo why separate from else
throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggGroup'));
-
- // Is it a GUID
} else if (is_numeric($guid)) {
+ // $guid is a GUID so load entity
if (!$this->load($guid)) {
throw new IOException(elgg_echo('IOException:FailedToLoadGUID', array(get_class(), $guid)));
}
@@ -338,7 +335,7 @@ class ElggGroup extends ElggEntity
$this->attributes = $attrs;
$this->attributes['tables_loaded'] = 2;
- cache_entity($this);
+ _elgg_cache_entity($this);
return true;
}
@@ -355,7 +352,12 @@ class ElggGroup extends ElggEntity
}
// Now save specific stuff
- return create_group_entity($this->get('guid'), $this->get('name'), $this->get('description'));
+
+ _elgg_disable_caching_for_entity($this->guid);
+ $ret = create_group_entity($this->get('guid'), $this->get('name'), $this->get('description'));
+ _elgg_enable_caching_for_entity($this->guid);
+
+ return $ret;
}
// EXPORTABLE INTERFACE ////////////////////////////////////////////////////////////
diff --git a/engine/classes/ElggLRUCache.php b/engine/classes/ElggLRUCache.php
new file mode 100644
index 000000000..f51af2ed7
--- /dev/null
+++ b/engine/classes/ElggLRUCache.php
@@ -0,0 +1,181 @@
+<?php
+
+/**
+ * Least Recently Used Cache
+ *
+ * A fixed sized cache that removes the element used last when it reaches its
+ * size limit.
+ *
+ * Based on https://github.com/cash/LRUCache
+ *
+ * @access private
+ *
+ * @package Elgg.Core
+ * @subpackage Cache
+ */
+class ElggLRUCache implements ArrayAccess {
+ /** @var int */
+ protected $maximumSize;
+
+ /**
+ * The front of the array contains the LRU element
+ *
+ * @var array
+ */
+ protected $data = array();
+
+ /**
+ * Create a LRU Cache
+ *
+ * @param int $size The size of the cache
+ * @throws InvalidArgumentException
+ */
+ public function __construct($size) {
+ if (!is_int($size) || $size <= 0) {
+ throw new InvalidArgumentException();
+ }
+ $this->maximumSize = $size;
+ }
+
+ /**
+ * Get the value cached with this key
+ *
+ * @param int|string $key The key. Strings that are ints are cast to ints.
+ * @param mixed $default The value to be returned if key not found. (Optional)
+ * @return mixed
+ */
+ public function get($key, $default = null) {
+ if (isset($this->data[$key])) {
+ $this->recordAccess($key);
+ return $this->data[$key];
+ } else {
+ return $default;
+ }
+ }
+
+ /**
+ * Add something to the cache
+ *
+ * @param int|string $key The key. Strings that are ints are cast to ints.
+ * @param mixed $value The value to cache
+ * @return void
+ */
+ public function set($key, $value) {
+ if (isset($this->data[$key])) {
+ $this->data[$key] = $value;
+ $this->recordAccess($key);
+ } else {
+ $this->data[$key] = $value;
+ if ($this->size() > $this->maximumSize) {
+ // remove least recently used element (front of array)
+ reset($this->data);
+ unset($this->data[key($this->data)]);
+ }
+ }
+ }
+
+ /**
+ * Get the number of elements in the cache
+ *
+ * @return int
+ */
+ public function size() {
+ return count($this->data);
+ }
+
+ /**
+ * Does the cache contain an element with this key
+ *
+ * @param int|string $key The key
+ * @return boolean
+ */
+ public function containsKey($key) {
+ return isset($this->data[$key]);
+ }
+
+ /**
+ * Remove the element with this key.
+ *
+ * @param int|string $key The key
+ * @return mixed Value or null if not set
+ */
+ public function remove($key) {
+ if (isset($this->data[$key])) {
+ $value = $this->data[$key];
+ unset($this->data[$key]);
+ return $value;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Clear the cache
+ *
+ * @return void
+ */
+ public function clear() {
+ $this->data = array();
+ }
+
+ /**
+ * Moves the element from current position to end of array
+ *
+ * @param int|string $key The key
+ * @return void
+ */
+ protected function recordAccess($key) {
+ $value = $this->data[$key];
+ unset($this->data[$key]);
+ $this->data[$key] = $value;
+ }
+
+ /**
+ * Assigns a value for the specified key
+ *
+ * @see ArrayAccess::offsetSet()
+ *
+ * @param int|string $key The key to assign the value to.
+ * @param mixed $value The value to set.
+ * @return void
+ */
+ public function offsetSet($key, $value) {
+ $this->set($key, $value);
+ }
+
+ /**
+ * Get the value for specified key
+ *
+ * @see ArrayAccess::offsetGet()
+ *
+ * @param int|string $key The key to retrieve.
+ * @return mixed
+ */
+ public function offsetGet($key) {
+ return $this->get($key);
+ }
+
+ /**
+ * Unsets a key.
+ *
+ * @see ArrayAccess::offsetUnset()
+ *
+ * @param int|string $key The key to unset.
+ * @return void
+ */
+ public function offsetUnset($key) {
+ $this->remove($key);
+ }
+
+ /**
+ * Does key exist?
+ *
+ * @see ArrayAccess::offsetExists()
+ *
+ * @param int|string $key A key to check for.
+ * @return boolean
+ */
+ public function offsetExists($key) {
+ return $this->containsKey($key);
+ }
+}
diff --git a/engine/classes/ElggMenuBuilder.php b/engine/classes/ElggMenuBuilder.php
index 639e34755..276cb6b2c 100644
--- a/engine/classes/ElggMenuBuilder.php
+++ b/engine/classes/ElggMenuBuilder.php
@@ -128,8 +128,10 @@ class ElggMenuBuilder {
$parent_name = $menu_item->getParentName();
if (array_key_exists($parent_name, $current_gen)) {
$next_gen[$menu_item->getName()] = $menu_item;
- $current_gen[$parent_name]->addChild($menu_item);
- $menu_item->setParent($current_gen[$parent_name]);
+ if (!in_array($menu_item, $current_gen[$parent_name]->getData('children'))) {
+ $current_gen[$parent_name]->addChild($menu_item);
+ $menu_item->setParent($current_gen[$parent_name]);
+ }
unset($children[$index]);
}
}
@@ -235,8 +237,8 @@ class ElggMenuBuilder {
/**
* Compare two menu items by their display text
*
- * @param ElggMenuItem $a
- * @param ElggMenuItem $b
+ * @param ElggMenuItem $a Menu item
+ * @param ElggMenuItem $b Menu item
* @return bool
*/
public static function compareByText($a, $b) {
@@ -253,8 +255,8 @@ class ElggMenuBuilder {
/**
* Compare two menu items by their identifiers
*
- * @param ElggMenuItem $a
- * @param ElggMenuItem $b
+ * @param ElggMenuItem $a Menu item
+ * @param ElggMenuItem $b Menu item
* @return bool
*/
public static function compareByName($a, $b) {
@@ -271,8 +273,8 @@ class ElggMenuBuilder {
/**
* Compare two menu items by their priority
*
- * @param ElggMenuItem $a
- * @param ElggMenuItem $b
+ * @param ElggMenuItem $a Menu item
+ * @param ElggMenuItem $b Menu item
* @return bool
*
* @todo change name to compareByPriority
diff --git a/engine/classes/ElggObject.php b/engine/classes/ElggObject.php
index 6263f84f6..aeaa3ba5c 100644
--- a/engine/classes/ElggObject.php
+++ b/engine/classes/ElggObject.php
@@ -66,21 +66,18 @@ class ElggObject extends ElggEntity {
$msg = elgg_echo('IOException:FailedToLoadGUID', array(get_class(), $guid->guid));
throw new IOException($msg);
}
-
- // Is $guid is an ElggObject? Use a copy constructor
} else if ($guid instanceof ElggObject) {
+ // $guid is an ElggObject so this is a copy constructor
elgg_deprecated_notice('This type of usage of the ElggObject constructor was deprecated. Please use the clone method.', 1.7);
foreach ($guid->attributes as $key => $value) {
$this->attributes[$key] = $value;
}
-
- // Is this is an ElggEntity but not an ElggObject = ERROR!
} else if ($guid instanceof ElggEntity) {
+ // @todo remove - do not need separate exception
throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggObject'));
-
- // Is it a GUID
} else if (is_numeric($guid)) {
+ // $guid is a GUID so load
if (!$this->load($guid)) {
throw new IOException(elgg_echo('IOException:FailedToLoadGUID', array(get_class(), $guid)));
}
@@ -110,7 +107,7 @@ class ElggObject extends ElggEntity {
$this->attributes = $attrs;
$this->attributes['tables_loaded'] = 2;
- cache_entity($this);
+ _elgg_cache_entity($this);
return true;
}
@@ -129,8 +126,12 @@ class ElggObject extends ElggEntity {
}
// Save ElggObject-specific attributes
- return create_object_entity($this->get('guid'), $this->get('title'),
- $this->get('description'));
+
+ _elgg_disable_caching_for_entity($this->guid);
+ $ret = create_object_entity($this->get('guid'), $this->get('title'), $this->get('description'));
+ _elgg_enable_caching_for_entity($this->guid);
+
+ return $ret;
}
/**
diff --git a/engine/classes/ElggPlugin.php b/engine/classes/ElggPlugin.php
index ae447bddb..7bf6eb1df 100644
--- a/engine/classes/ElggPlugin.php
+++ b/engine/classes/ElggPlugin.php
@@ -350,11 +350,14 @@ class ElggPlugin extends ElggObject {
*/
public function unsetAllSettings() {
$db_prefix = get_config('dbprefix');
- $ps_prefix = elgg_namespace_plugin_private_setting('setting', '');
+
+ $us_prefix = elgg_namespace_plugin_private_setting('user_setting', '', $this->getID());
+ $is_prefix = elgg_namespace_plugin_private_setting('internal', '', $this->getID());
$q = "DELETE FROM {$db_prefix}private_settings
WHERE entity_guid = $this->guid
- AND name NOT LIKE '$ps_prefix%'";
+ AND name NOT LIKE '$us_prefix%'
+ AND name NOT LIKE '$is_prefix%'";
return delete_data($q);
}
@@ -546,7 +549,7 @@ class ElggPlugin extends ElggObject {
* Returns if the plugin is complete, meaning has all required files
* and Elgg can read them and they make sense.
*
- * @todo bad name? This could be confused with isValid() from ElggPackage.
+ * @todo bad name? This could be confused with isValid() from ElggPluginPackage.
*
* @return bool
*/
@@ -649,8 +652,8 @@ class ElggPlugin extends ElggObject {
// Note: this will not run re-run the init hooks!
if ($return) {
if ($this->canReadFile('activate.php')) {
- $flags = ELGG_PLUGIN_INCLUDE_START | ELGG_PLUGIN_REGISTER_CLASSES
- | ELGG_PLUGIN_REGISTER_LANGUAGES | ELGG_PLUGIN_REGISTER_VIEWS;
+ $flags = ELGG_PLUGIN_INCLUDE_START | ELGG_PLUGIN_REGISTER_CLASSES |
+ ELGG_PLUGIN_REGISTER_LANGUAGES | ELGG_PLUGIN_REGISTER_VIEWS;
$this->start($flags);
diff --git a/engine/classes/ElggPluginPackage.php b/engine/classes/ElggPluginPackage.php
index 209242288..37eb4bf4d 100644
--- a/engine/classes/ElggPluginPackage.php
+++ b/engine/classes/ElggPluginPackage.php
@@ -294,6 +294,7 @@ class ElggPluginPackage {
return true;
}
+ $this->errorMsg = elgg_echo('unknown_error');
return false;
}
diff --git a/engine/classes/ElggPriorityList.php b/engine/classes/ElggPriorityList.php
index b5f8fe163..416df885c 100644
--- a/engine/classes/ElggPriorityList.php
+++ b/engine/classes/ElggPriorityList.php
@@ -165,9 +165,9 @@ class ElggPriorityList
/**
* Move an existing element to a new priority.
*
- * @param mixed $element The element to move
- * @param int $new_priority The new priority for the element
- * @param bool $strict Whether to check the type of the element match
+ * @param mixed $element The element to move
+ * @param int $new_priority The new priority for the element
+ * @param bool $strict Whether to check the type of the element match
* @return bool
*/
public function move($element, $new_priority, $strict = false) {
@@ -354,7 +354,12 @@ class ElggPriorityList
return ($key !== NULL && $key !== FALSE);
}
- // Countable
+ /**
+ * Countable interface
+ *
+ * @see Countable::count()
+ * @return int
+ */
public function count() {
return count($this->elements);
}
diff --git a/engine/classes/ElggSite.php b/engine/classes/ElggSite.php
index 1a34df195..dd996fe98 100644
--- a/engine/classes/ElggSite.php
+++ b/engine/classes/ElggSite.php
@@ -77,28 +77,24 @@ class ElggSite extends ElggEntity {
$msg = elgg_echo('IOException:FailedToLoadGUID', array(get_class(), $guid->guid));
throw new IOException($msg);
}
-
- // Is $guid is an ElggSite? Use a copy constructor
} else if ($guid instanceof ElggSite) {
+ // $guid is an ElggSite so this is a copy constructor
elgg_deprecated_notice('This type of usage of the ElggSite constructor was deprecated. Please use the clone method.', 1.7);
foreach ($guid->attributes as $key => $value) {
$this->attributes[$key] = $value;
}
-
- // Is this is an ElggEntity but not an ElggSite = ERROR!
} else if ($guid instanceof ElggEntity) {
+ // @todo remove and just use else clause
throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggSite'));
-
- // See if this is a URL
} else if (strpos($guid, "http") !== false) {
+ // url so retrieve by url
$guid = get_site_by_url($guid);
foreach ($guid->attributes as $key => $value) {
$this->attributes[$key] = $value;
}
-
- // Is it a GUID
} else if (is_numeric($guid)) {
+ // $guid is a GUID so load
if (!$this->load($guid)) {
throw new IOException(elgg_echo('IOException:FailedToLoadGUID', array(get_class(), $guid)));
}
@@ -128,7 +124,7 @@ class ElggSite extends ElggEntity {
$this->attributes = $attrs;
$this->attributes['tables_loaded'] = 2;
- cache_entity($this);
+ _elgg_cache_entity($this);
return true;
}
diff --git a/engine/classes/ElggStaticVariableCache.php b/engine/classes/ElggStaticVariableCache.php
index 17d849400..9c14fdfba 100644
--- a/engine/classes/ElggStaticVariableCache.php
+++ b/engine/classes/ElggStaticVariableCache.php
@@ -11,7 +11,7 @@ class ElggStaticVariableCache extends ElggSharedMemoryCache {
/**
* The cache.
*
- * @var unknown_type
+ * @var array
*/
private static $__cache;
@@ -22,7 +22,7 @@ class ElggStaticVariableCache extends ElggSharedMemoryCache {
* memory, optionally with a given namespace (to avoid overlap).
*
* @param string $namespace The namespace for this cache to write to.
- * @note namespaces of the same name are shared!
+ * @warning namespaces of the same name are shared!
*/
function __construct($namespace = 'default') {
$this->setNamespace($namespace);
@@ -80,7 +80,7 @@ class ElggStaticVariableCache extends ElggSharedMemoryCache {
}
/**
- * This was probably meant to delete everything?
+ * Clears the cache for a particular namespace
*
* @return void
*/
diff --git a/engine/classes/ElggTranslit.php b/engine/classes/ElggTranslit.php
index 676c59fc8..b4bf87797 100644
--- a/engine/classes/ElggTranslit.php
+++ b/engine/classes/ElggTranslit.php
@@ -20,11 +20,10 @@
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*
- * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
- * @author Jonathan H. Wage <jonwage@gmail.com>
- *
- * @author Steve Clay <steve@mrclay.org>
- * @package Elgg.Core
+ * @package Elgg.Core
+ * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ * @author Steve Clay <steve@mrclay.org>
*
* @access private Plugin authors should not use this directly
*/
@@ -32,8 +31,9 @@ class ElggTranslit {
/**
* Create a version of a string for embedding in a URL
- * @param string $string a UTF-8 string
- * @param string $separator
+ *
+ * @param string $string A UTF-8 string
+ * @param string $separator The character to separate words with
* @return string
*/
static public function urlize($string, $separator = '-') {
@@ -49,24 +49,29 @@ class ElggTranslit {
// Internationalization, AND 日本語!
$string = self::transliterateAscii($string);
- // more translation
+ // allow HTML tags in titles
+ $string = preg_replace('~<([a-zA-Z][^>]*)>~', ' $1 ', $string);
+
+ // more substitutions
+ // @todo put these somewhere else
$string = strtr($string, array(
- // Euro/GBP
- "\xE2\x82\xAC" /* € */ => 'E', "\xC2\xA3" /* £ */ => 'GBP',
+ // currency
+ "\xE2\x82\xAC" /* € */ => ' E ',
+ "\xC2\xA3" /* £ */ => ' GBP ',
));
// remove all ASCII except 0-9a-zA-Z, hyphen, underscore, and whitespace
// note: "x" modifier did not work with this pattern.
$string = preg_replace('~['
- . '\x00-\x08' # control chars
- . '\x0b\x0c' # vert tab, form feed
- . '\x0e-\x1f' # control chars
- . '\x21-\x2c' # ! ... ,
- . '\x2e\x2f' # . slash
- . '\x3a-\x40' # : ... @
- . '\x5b-\x5e' # [ ... ^
- . '\x60' # `
- . '\x7b-\x7f' # { ... DEL
+ . '\x00-\x08' // control chars
+ . '\x0b\x0c' // vert tab, form feed
+ . '\x0e-\x1f' // control chars
+ . '\x21-\x2c' // ! ... ,
+ . '\x2e\x2f' // . slash
+ . '\x3a-\x40' // : ... @
+ . '\x5b-\x5e' // [ ... ^
+ . '\x60' // `
+ . '\x7b-\x7f' // { ... DEL
. ']~', '', $string);
$string = strtr($string, '', '');
@@ -80,10 +85,10 @@ class ElggTranslit {
// note: we cannot use [^0-9a-zA-Z] because that matches multibyte chars.
// note: "x" modifier did not work with this pattern.
$pattern = '~['
- . '\x00-\x2f' # controls ... slash
- . '\x3a-\x40' # : ... @
- . '\x5b-\x60' # [ ... `
- . '\x7b-\x7f' # { ... DEL
+ . '\x00-\x2f' // controls ... slash
+ . '\x3a-\x40' // : ... @
+ . '\x5b-\x60' // [ ... `
+ . '\x7b-\x7f' // { ... DEL
. ']+~x';
// ['internationalization', 'and', '日本語']
@@ -98,6 +103,7 @@ class ElggTranslit {
/**
* Transliterate Western multibyte chars to ASCII
+ *
* @param string $utf8 a UTF-8 string
* @return string
*/
@@ -247,6 +253,7 @@ class ElggTranslit {
/**
* Tests that "normalizer_normalize" exists and works
+ *
* @return bool
*/
static public function hasNormalizerSupport() {
@@ -255,7 +262,7 @@ class ElggTranslit {
$form_c = "\xC3\x85"; // 'LATIN CAPITAL LETTER A WITH RING ABOVE' (U+00C5)
$form_d = "A\xCC\x8A"; // A followed by 'COMBINING RING ABOVE' (U+030A)
$ret = (function_exists('normalizer_normalize')
- && $form_c === normalizer_normalize($form_d));
+ && $form_c === normalizer_normalize($form_d));
}
return $ret;
}
diff --git a/engine/classes/ElggUser.php b/engine/classes/ElggUser.php
index 6c1cdc1de..6163f9b62 100644
--- a/engine/classes/ElggUser.php
+++ b/engine/classes/ElggUser.php
@@ -40,6 +40,9 @@ class ElggUser extends ElggEntity
$this->attributes['code'] = NULL;
$this->attributes['banned'] = "no";
$this->attributes['admin'] = 'no';
+ $this->attributes['prev_last_action'] = NULL;
+ $this->attributes['last_login'] = NULL;
+ $this->attributes['prev_last_login'] = NULL;
$this->attributes['tables_split'] = 2;
}
@@ -65,30 +68,26 @@ class ElggUser extends ElggEntity
$msg = elgg_echo('IOException:FailedToLoadGUID', array(get_class(), $guid->guid));
throw new IOException($msg);
}
-
- // See if this is a username
} else if (is_string($guid)) {
+ // $guid is a username
$user = get_user_by_username($guid);
if ($user) {
foreach ($user->attributes as $key => $value) {
$this->attributes[$key] = $value;
}
}
-
- // Is $guid is an ElggUser? Use a copy constructor
} else if ($guid instanceof ElggUser) {
+ // $guid is an ElggUser so this is a copy constructor
elgg_deprecated_notice('This type of usage of the ElggUser constructor was deprecated. Please use the clone method.', 1.7);
foreach ($guid->attributes as $key => $value) {
$this->attributes[$key] = $value;
}
-
- // Is this is an ElggEntity but not an ElggUser = ERROR!
} else if ($guid instanceof ElggEntity) {
+ // @todo why have a special case here
throw new InvalidParameterException(elgg_echo('InvalidParameterException:NonElggUser'));
-
- // Is it a GUID
} else if (is_numeric($guid)) {
+ // $guid is a GUID so load entity
if (!$this->load($guid)) {
throw new IOException(elgg_echo('IOException:FailedToLoadGUID', array(get_class(), $guid)));
}
@@ -116,7 +115,7 @@ class ElggUser extends ElggEntity
$this->attributes = $attrs;
$this->attributes['tables_loaded'] = 2;
- cache_entity($this);
+ _elgg_cache_entity($this);
return true;
}
@@ -133,9 +132,13 @@ class ElggUser extends ElggEntity
}
// Now save specific stuff
- return create_user_entity($this->get('guid'), $this->get('name'), $this->get('username'),
+ _elgg_disable_caching_for_entity($this->guid);
+ $ret = create_user_entity($this->get('guid'), $this->get('name'), $this->get('username'),
$this->get('password'), $this->get('salt'), $this->get('email'), $this->get('language'),
$this->get('code'));
+ _elgg_enable_caching_for_entity($this->guid);
+
+ return $ret;
}
/**
diff --git a/engine/classes/ElggVolatileMetadataCache.php b/engine/classes/ElggVolatileMetadataCache.php
index 8a33c198d..4acda7cee 100644
--- a/engine/classes/ElggVolatileMetadataCache.php
+++ b/engine/classes/ElggVolatileMetadataCache.php
@@ -33,9 +33,11 @@ class ElggVolatileMetadataCache {
protected $ignoreAccess = null;
/**
- * @param int $entity_guid
- *
- * @param array $values
+ * Cache metadata for an entity
+ *
+ * @param int $entity_guid The GUID of the entity
+ * @param array $values The metadata values to cache
+ * @return void
*/
public function saveAll($entity_guid, array $values) {
if (!$this->getIgnoreAccess()) {
@@ -45,8 +47,9 @@ class ElggVolatileMetadataCache {
}
/**
- * @param int $entity_guid
- *
+ * Get the metadata for an entity
+ *
+ * @param int $entity_guid The GUID of the entity
* @return array
*/
public function loadAll($entity_guid) {
@@ -61,15 +64,17 @@ class ElggVolatileMetadataCache {
* Declare that there may be fetch-able metadata names in storage that this
* cache doesn't know about
*
- * @param int $entity_guid
+ * @param int $entity_guid The GUID of the entity
+ * @return void
*/
public function markOutOfSync($entity_guid) {
unset($this->isSynchronized[$entity_guid]);
}
/**
- * @param $entity_guid
- *
+ * Have all the metadata for this entity been cached?
+ *
+ * @param int $entity_guid The GUID of the entity
* @return bool
*/
public function isSynchronized($entity_guid) {
@@ -77,13 +82,15 @@ class ElggVolatileMetadataCache {
}
/**
- * @param int $entity_guid
- *
- * @param string $name
- *
- * @param array|int|string|null $value null means it is known that there is no
- * fetch-able metadata under this name
- * @param bool $allow_multiple
+ * Cache a piece of metadata
+ *
+ * @param int $entity_guid The GUID of the entity
+ * @param string $name The metadata name
+ * @param array|int|string|null $value The metadata value. null means it is
+ * known that there is no fetch-able
+ * metadata under this name
+ * @param bool $allow_multiple Can the metadata be an array
+ * @return void
*/
public function save($entity_guid, $name, $value, $allow_multiple = false) {
if ($this->getIgnoreAccess()) {
@@ -115,10 +122,8 @@ class ElggVolatileMetadataCache {
* function's return value should be trusted (otherwise a null return value
* is ambiguous).
*
- * @param int $entity_guid
- *
- * @param string $name
- *
+ * @param int $entity_guid The GUID of the entity
+ * @param string $name The metadata name
* @return array|string|int|null null = value does not exist
*/
public function load($entity_guid, $name) {
@@ -133,9 +138,9 @@ class ElggVolatileMetadataCache {
* Forget about this metadata entry. We don't want to try to guess what the
* next fetch from storage will return
*
- * @param int $entity_guid
- *
- * @param string $name
+ * @param int $entity_guid The GUID of the entity
+ * @param string $name The metadata name
+ * @return void
*/
public function markUnknown($entity_guid, $name) {
unset($this->values[$entity_guid][$name]);
@@ -145,10 +150,8 @@ class ElggVolatileMetadataCache {
/**
* If true, load() will return an accurate value for this name
*
- * @param int $entity_guid
- *
- * @param string $name
- *
+ * @param int $entity_guid The GUID of the entity
+ * @param string $name The metadata name
* @return bool
*/
public function isKnown($entity_guid, $name) {
@@ -163,10 +166,8 @@ class ElggVolatileMetadataCache {
/**
* Declare that metadata under this name is known to be not fetch-able from storage
*
- * @param int $entity_guid
- *
- * @param string $name
- *
+ * @param int $entity_guid The GUID of the entity
+ * @param string $name The metadata name
* @return array
*/
public function markEmpty($entity_guid, $name) {
@@ -176,7 +177,8 @@ class ElggVolatileMetadataCache {
/**
* Forget about all metadata for an entity
*
- * @param int $entity_guid
+ * @param int $entity_guid The GUID of the entity
+ * @return void
*/
public function clear($entity_guid) {
$this->values[$entity_guid] = array();
@@ -185,6 +187,8 @@ class ElggVolatileMetadataCache {
/**
* Clear entire cache and mark all entities as out of sync
+ *
+ * @return void
*/
public function flush() {
$this->values = array();
@@ -197,7 +201,8 @@ class ElggVolatileMetadataCache {
*
* This setting makes this component a little more loosely-coupled.
*
- * @param bool $ignore
+ * @param bool $ignore Whether to ignore access or not
+ * @return void
*/
public function setIgnoreAccess($ignore) {
$this->ignoreAccess = (bool) $ignore;
@@ -205,12 +210,16 @@ class ElggVolatileMetadataCache {
/**
* Tell the cache to call elgg_get_ignore_access() to determing access status.
+ *
+ * @return void
*/
public function unsetIgnoreAccess() {
$this->ignoreAccess = null;
}
/**
+ * Get the ignore access value
+ *
* @return bool
*/
protected function getIgnoreAccess() {
@@ -225,12 +234,10 @@ class ElggVolatileMetadataCache {
* Invalidate based on options passed to the global *_metadata functions
*
* @param string $action Action performed on metadata. "delete", "disable", or "enable"
- *
- * @param array $options Options passed to elgg_(delete|disable|enable)_metadata
- *
- * "guid" if given, invalidation will be limited to this entity
- *
- * "metadata_name" if given, invalidation will be limited to metadata with this name
+ * @param array $options Options passed to elgg_(delete|disable|enable)_metadata
+ * "guid" if given, invalidation will be limited to this entity
+ * "metadata_name" if given, invalidation will be limited to metadata with this name
+ * @return void
*/
public function invalidateByOptions($action, array $options) {
// remove as little as possible, optimizing for common cases
@@ -254,7 +261,10 @@ class ElggVolatileMetadataCache {
}
/**
- * @param int|array $guids
+ * Populate the cache from a set of entities
+ *
+ * @param int|array $guids Array of or single GUIDs
+ * @return void
*/
public function populateFromEntities($guids) {
if (empty($guids)) {
@@ -318,9 +328,7 @@ class ElggVolatileMetadataCache {
* cache if RAM usage becomes an issue.
*
* @param array $guids GUIDs of entities to examine
- *
- * @param int $limit Limit in characters of all metadata (with ints casted to strings)
- *
+ * @param int $limit Limit in characters of all metadata (with ints casted to strings)
* @return array
*/
public function filterMetadataHeavyEntities(array $guids, $limit = 1024000) {
diff --git a/engine/classes/ElggWidget.php b/engine/classes/ElggWidget.php
index c123e5032..66191bf47 100644
--- a/engine/classes/ElggWidget.php
+++ b/engine/classes/ElggWidget.php
@@ -146,10 +146,15 @@ class ElggWidget extends ElggObject {
}
}
+ $bottom_rank = count($widgets);
+ if ($column == $this->column) {
+ $bottom_rank--;
+ }
+
if ($rank == 0) {
// top of the column
$this->order = reset($widgets)->order - 10;
- } elseif ($rank == (count($widgets) - 1)) {
+ } elseif ($rank == $bottom_rank) {
// bottom of the column of active widgets
$this->order = end($widgets)->order + 10;
} else {
diff --git a/engine/classes/ElggXMLElement.php b/engine/classes/ElggXMLElement.php
index 4e4b7e63c..6f2633e25 100644
--- a/engine/classes/ElggXMLElement.php
+++ b/engine/classes/ElggXMLElement.php
@@ -76,6 +76,12 @@ class ElggXMLElement {
return $result;
}
+ /**
+ * Override ->
+ *
+ * @param string $name Property name
+ * @return mixed
+ */
function __get($name) {
switch ($name) {
case 'name':
@@ -94,6 +100,12 @@ class ElggXMLElement {
return null;
}
+ /**
+ * Override isset
+ *
+ * @param string $name Property name
+ * @return boolean
+ */
function __isset($name) {
switch ($name) {
case 'name':
diff --git a/engine/handlers/cache_handler.php b/engine/handlers/cache_handler.php
index 9848d3531..36fc665bb 100644
--- a/engine/handlers/cache_handler.php
+++ b/engine/handlers/cache_handler.php
@@ -88,20 +88,18 @@ header("ETag: \"$etag\"");
$filename = $dataroot . 'views_simplecache/' . md5($viewtype . $view);
if (file_exists($filename)) {
- $contents = file_get_contents($filename);
+ readfile($filename);
} else {
// someone trying to access a non-cached file or a race condition with cache flushing
mysql_close($mysql_dblink);
require_once(dirname(dirname(__FILE__)) . "/start.php");
global $CONFIG;
- if (!isset($CONFIG->views->simplecache[$view])) {
+ if (!in_array($view, $CONFIG->views->simplecache)) {
header("HTTP/1.1 404 Not Found");
exit;
}
elgg_set_viewtype($viewtype);
- $contents = elgg_view($view);
+ echo elgg_view($view);
}
-
-echo $contents;
diff --git a/engine/lib/actions.php b/engine/lib/actions.php
index ac6325813..56936f582 100644
--- a/engine/lib/actions.php
+++ b/engine/lib/actions.php
@@ -65,18 +65,16 @@ function action($action, $forwarder = "") {
// @todo REMOVE THESE ONCE #1509 IS IN PLACE.
// Allow users to disable plugins without a token in order to
// remove plugins that are incompatible.
- // Login and logout are for convenience.
+ // Logout for convenience.
// file/download (see #2010)
$exceptions = array(
'admin/plugins/disable',
'logout',
- 'login',
'file/download',
);
if (!in_array($action, $exceptions)) {
- // All actions require a token.
- action_gatekeeper();
+ action_gatekeeper($action);
}
$forwarder = str_replace(elgg_get_site_url(), "", $forwarder);
@@ -189,6 +187,26 @@ function elgg_unregister_action($action) {
}
/**
+ * Is the token timestamp within acceptable range?
+ *
+ * @param int $ts timestamp from the CSRF token
+ *
+ * @return bool
+ */
+function _elgg_validate_token_timestamp($ts) {
+ $action_token_timeout = elgg_get_config('action_token_timeout');
+ // default is 2 hours
+ $timeout = ($action_token_timeout !== null) ? $action_token_timeout : 2;
+
+ $hour = 60 * 60;
+ $timeout = $timeout * $hour;
+ $now = time();
+
+ // Validate time to ensure its not crazy
+ return ($timeout == 0 || ($ts > $now - $timeout) && ($ts < $now + $timeout));
+}
+
+/**
* Validate an action token.
*
* Calls to actions will automatically validate tokens. If tokens are not
@@ -206,8 +224,6 @@ function elgg_unregister_action($action) {
* @access private
*/
function validate_action_token($visibleerrors = TRUE, $token = NULL, $ts = NULL) {
- global $CONFIG;
-
if (!$token) {
$token = get_input('__elgg_token');
}
@@ -216,29 +232,18 @@ function validate_action_token($visibleerrors = TRUE, $token = NULL, $ts = NULL)
$ts = get_input('__elgg_ts');
}
- if (!isset($CONFIG->action_token_timeout)) {
- // default to 2 hours
- $timeout = 2;
- } else {
- $timeout = $CONFIG->action_token_timeout;
- }
-
$session_id = session_id();
if (($token) && ($ts) && ($session_id)) {
// generate token, check with input and forward if invalid
- $generated_token = generate_action_token($ts);
+ $required_token = generate_action_token($ts);
// Validate token
- if ($token == $generated_token) {
- $hour = 60 * 60;
- $timeout = $timeout * $hour;
- $now = time();
-
- // Validate time to ensure its not crazy
- if ($timeout == 0 || ($ts > $now - $timeout) && ($ts < $now + $timeout)) {
+ if ($token == $required_token) {
+
+ if (_elgg_validate_token_timestamp($ts)) {
// We have already got this far, so unless anything
- // else says something to the contry we assume we're ok
+ // else says something to the contrary we assume we're ok
$returnval = true;
$returnval = elgg_trigger_plugin_hook('action_gatekeeper:permissions:check', 'all', array(
@@ -294,12 +299,33 @@ function validate_action_token($visibleerrors = TRUE, $token = NULL, $ts = NULL)
* This function verifies form input for security features (like a generated token),
* and forwards if they are invalid.
*
+ * @param string $action The action being performed
+ *
* @return mixed True if valid or redirects.
* @access private
*/
-function action_gatekeeper() {
- if (validate_action_token()) {
- return TRUE;
+function action_gatekeeper($action) {
+ if ($action === 'login') {
+ if (validate_action_token(false)) {
+ return true;
+ }
+
+ $token = get_input('__elgg_token');
+ $ts = (int)get_input('__elgg_ts');
+ if ($token && _elgg_validate_token_timestamp($ts)) {
+ // The tokens are present and the time looks valid: this is probably a mismatch due to the
+ // login form being on a different domain.
+ register_error(elgg_echo('actiongatekeeper:crosssitelogin'));
+
+
+ forward('login', 'csrf');
+ }
+
+ // let the validator send an appropriate msg
+ validate_action_token();
+
+ } elseif (validate_action_token()) {
+ return true;
}
forward(REFERER, 'csrf');
diff --git a/engine/lib/admin.php b/engine/lib/admin.php
index ec19a5476..7f82108c0 100644
--- a/engine/lib/admin.php
+++ b/engine/lib/admin.php
@@ -134,11 +134,11 @@ function elgg_delete_admin_notice($id) {
}
/**
- * List all admin messages.
+ * Get admin notices. An admin must be logged in since the notices are private.
*
* @param int $limit Limit
*
- * @return array List of admin notices
+ * @return array Array of admin notices
* @since 1.8.0
*/
function elgg_get_admin_notices($limit = 10) {
@@ -158,11 +158,13 @@ function elgg_get_admin_notices($limit = 10) {
* @since 1.8.0
*/
function elgg_admin_notice_exists($id) {
+ $old_ia = elgg_set_ignore_access(true);
$notice = elgg_get_entities_from_metadata(array(
'type' => 'object',
'subtype' => 'admin_notice',
'metadata_name_value_pair' => array('name' => 'admin_notice_id', 'value' => $id)
));
+ elgg_set_ignore_access($old_ia);
return ($notice) ? TRUE : FALSE;
}
@@ -468,14 +470,18 @@ function admin_page_handler($page) {
$vars = array('page' => $page);
// special page for plugin settings since we create the form for them
- if ($page[0] == 'plugin_settings' && isset($page[1]) &&
- (elgg_view_exists("settings/{$page[1]}/edit") || elgg_view_exists("plugins/{$page[1]}/settings"))) {
+ if ($page[0] == 'plugin_settings') {
+ if (isset($page[1]) && (elgg_view_exists("settings/{$page[1]}/edit") ||
+ elgg_view_exists("plugins/{$page[1]}/settings"))) {
- $view = 'admin/plugin_settings';
- $plugin = elgg_get_plugin_from_id($page[1]);
- $vars['plugin'] = $plugin;
+ $view = 'admin/plugin_settings';
+ $plugin = elgg_get_plugin_from_id($page[1]);
+ $vars['plugin'] = $plugin;
- $title = elgg_echo("admin:{$page[0]}");
+ $title = elgg_echo("admin:{$page[0]}");
+ } else {
+ forward('', '404');
+ }
} else {
$view = 'admin/' . implode('/', $page);
$title = elgg_echo("admin:{$page[0]}");
diff --git a/engine/lib/annotations.php b/engine/lib/annotations.php
index bd5ea1a1f..5e9b530de 100644
--- a/engine/lib/annotations.php
+++ b/engine/lib/annotations.php
@@ -224,7 +224,7 @@ function elgg_get_annotations(array $options = array()) {
* annotation_name(s), annotation_value(s), or guid(s) must be set.
*
* @param array $options An options array. {@See elgg_get_annotations()}
- * @return mixed Null if the metadata name is invalid. Bool on success or fail.
+ * @return bool|null true on success, false on failure, null if no annotations to delete.
* @since 1.8.0
*/
function elgg_delete_annotations(array $options) {
@@ -242,16 +242,20 @@ function elgg_delete_annotations(array $options) {
* @warning Unlike elgg_get_annotations() this will not accept an empty options array!
*
* @param array $options An options array. {@See elgg_get_annotations()}
- * @return mixed
+ * @return bool|null true on success, false on failure, null if no annotations disabled.
* @since 1.8.0
*/
function elgg_disable_annotations(array $options) {
if (!elgg_is_valid_options_for_batch_operation($options, 'annotations')) {
return false;
}
+
+ // if we can see hidden (disabled) we need to use the offset
+ // otherwise we risk an infinite loop if there are more than 50
+ $inc_offset = access_get_show_hidden_status();
$options['metastring_type'] = 'annotations';
- return elgg_batch_metastring_based_objects($options, 'elgg_batch_disable_callback', false);
+ return elgg_batch_metastring_based_objects($options, 'elgg_batch_disable_callback', $inc_offset);
}
/**
@@ -259,8 +263,11 @@ function elgg_disable_annotations(array $options) {
*
* @warning Unlike elgg_get_annotations() this will not accept an empty options array!
*
+ * @warning In order to enable annotations, you must first use
+ * {@link access_show_hidden_entities()}.
+ *
* @param array $options An options array. {@See elgg_get_annotations()}
- * @return mixed
+ * @return bool|null true on success, false on failure, null if no metadata enabled.
* @since 1.8.0
*/
function elgg_enable_annotations(array $options) {
@@ -416,8 +423,8 @@ function elgg_list_entities_from_annotations($options = array()) {
function elgg_get_entities_from_annotation_calculation($options) {
$db_prefix = elgg_get_config('dbprefix');
$defaults = array(
- 'calculation' => 'sum',
- 'order_by' => 'annotation_calculation desc'
+ 'calculation' => 'sum',
+ 'order_by' => 'annotation_calculation desc'
);
$options = array_merge($defaults, $options);
@@ -454,6 +461,12 @@ function elgg_get_entities_from_annotation_calculation($options) {
* @return string
*/
function elgg_list_entities_from_annotation_calculation($options) {
+ $defaults = array(
+ 'calculation' => 'sum',
+ 'order_by' => 'annotation_calculation desc'
+ );
+ $options = array_merge($defaults, $options);
+
return elgg_list_entities($options, 'elgg_get_entities_from_annotation_calculation');
}
@@ -532,15 +545,16 @@ function elgg_annotation_exists($entity_guid, $annotation_type, $owner_guid = NU
return FALSE;
}
- $entity_guid = (int)$entity_guid;
- $annotation_type = sanitise_string($annotation_type);
+ $entity_guid = sanitize_int($entity_guid);
+ $owner_guid = sanitize_int($owner_guid);
+ $annotation_type = sanitize_string($annotation_type);
- $sql = "select a.id" .
- " FROM {$CONFIG->dbprefix}annotations a, {$CONFIG->dbprefix}metastrings m " .
- " WHERE a.owner_guid={$owner_guid} AND a.entity_guid={$entity_guid} " .
- " AND a.name_id=m.id AND m.string='{$annotation_type}'";
+ $sql = "SELECT a.id FROM {$CONFIG->dbprefix}annotations a" .
+ " JOIN {$CONFIG->dbprefix}metastrings m ON a.name_id = m.id" .
+ " WHERE a.owner_guid = $owner_guid AND a.entity_guid = $entity_guid" .
+ " AND m.string = '$annotation_type'";
- if ($check_annotation = get_data_row($sql)) {
+ if (get_data_row($sql)) {
return TRUE;
}
diff --git a/engine/lib/cache.php b/engine/lib/cache.php
index 59359124e..3116c1a9b 100644
--- a/engine/lib/cache.php
+++ b/engine/lib/cache.php
@@ -208,6 +208,7 @@ function elgg_get_simplecache_url($type, $view) {
global $CONFIG;
$lastcache = (int)$CONFIG->lastcache;
$viewtype = elgg_get_viewtype();
+ elgg_register_simplecache_view("$type/$view");// see #5302
if (elgg_is_simplecache_enabled()) {
$url = elgg_get_site_url() . "cache/$type/$viewtype/$view.$lastcache.$type";
} else {
diff --git a/engine/lib/configuration.php b/engine/lib/configuration.php
index a0f297f0c..55e5bbd36 100644
--- a/engine/lib/configuration.php
+++ b/engine/lib/configuration.php
@@ -486,9 +486,9 @@ function get_config($name, $site_guid = 0) {
// @todo these haven't really been implemented in Elgg 1.8. Complete in 1.9.
// show dep message
if ($new_name) {
- // $msg = "Config value $name has been renamed as $new_name";
+ // $msg = "Config value $name has been renamed as $new_name";
$name = $new_name;
- // elgg_deprecated_notice($msg, $dep_version);
+ // elgg_deprecated_notice($msg, $dep_version);
}
// decide from where to return the value
diff --git a/engine/lib/database.php b/engine/lib/database.php
index 2b348366d..a7949788d 100644
--- a/engine/lib/database.php
+++ b/engine/lib/database.php
@@ -12,17 +12,19 @@
/**
* Query cache for all queries.
*
- * Each query and its results are stored in this array as:
+ * Each query and its results are stored in this cache as:
* <code>
- * $DB_QUERY_CACHE[$query] => array(result1, result2, ... resultN)
+ * $DB_QUERY_CACHE[query hash] => array(result1, result2, ... resultN)
* </code>
+ * @see elgg_query_runner() for details on the hash.
*
- * @warning be array this var may be an array or ElggStaticVariableCache depending on when called :(
+ * @warning Elgg used to set this as an empty array to turn off the cache
*
- * @global ElggStaticVariableCache|array $DB_QUERY_CACHE
+ * @global ElggLRUCache|null $DB_QUERY_CACHE
+ * @access private
*/
global $DB_QUERY_CACHE;
-$DB_QUERY_CACHE = array();
+$DB_QUERY_CACHE = null;
/**
* Queries to be executed upon shutdown.
@@ -40,6 +42,7 @@ $DB_QUERY_CACHE = array();
* </code>
*
* @global array $DB_DELAYED_QUERIES
+ * @access private
*/
global $DB_DELAYED_QUERIES;
$DB_DELAYED_QUERIES = array();
@@ -51,6 +54,7 @@ $DB_DELAYED_QUERIES = array();
* $dblink as $dblink[$name] => resource. Use get_db_link($name) to retrieve it.
*
* @global resource[] $dblink
+ * @access private
*/
global $dblink;
$dblink = array();
@@ -61,6 +65,7 @@ $dblink = array();
* Each call to the database increments this counter.
*
* @global integer $dbcalls
+ * @access private
*/
global $dbcalls;
$dbcalls = 0;
@@ -123,9 +128,8 @@ function establish_db_link($dblinkname = "readwrite") {
// Set up cache if global not initialized and query cache not turned off
if ((!$DB_QUERY_CACHE) && (!$db_cache_off)) {
- // @todo everywhere else this is assigned to array(), making it dangerous to call
- // object methods on this. We should consider making this an plain array
- $DB_QUERY_CACHE = new ElggStaticVariableCache('db_query_cache');
+ // @todo if we keep this cache in 1.9, expose the size as a config parameter
+ $DB_QUERY_CACHE = new ElggLRUCache(200);
}
}
@@ -395,16 +399,14 @@ function elgg_query_runner($query, $callback = null, $single = false) {
// Since we want to cache results of running the callback, we need to
// need to namespace the query with the callback and single result request.
- // http://trac.elgg.org/ticket/4049
+ // https://github.com/elgg/elgg/issues/4049
$hash = (string)$callback . (int)$single . $query;
// Is cached?
if ($DB_QUERY_CACHE) {
- $cached_query = $DB_QUERY_CACHE[$hash];
-
- if ($cached_query !== FALSE) {
+ if (isset($DB_QUERY_CACHE[$hash])) {
elgg_log("DB query $query results returned from cache (hash: $hash)", 'NOTICE');
- return $cached_query;
+ return $DB_QUERY_CACHE[$hash];
}
}
@@ -456,19 +458,12 @@ function elgg_query_runner($query, $callback = null, $single = false) {
* @access private
*/
function insert_data($query) {
- global $DB_QUERY_CACHE;
elgg_log("DB query $query", 'NOTICE');
$dblink = get_db_link('write');
- // Invalidate query cache
- if ($DB_QUERY_CACHE) {
- /* @var ElggStaticVariableCache $DB_QUERY_CACHE */
- $DB_QUERY_CACHE->clear();
- }
-
- elgg_log("Query cache invalidated", 'NOTICE');
+ _elgg_invalidate_query_cache();
if (execute_query("$query", $dblink)) {
return mysql_insert_id($dblink);
@@ -478,7 +473,7 @@ function insert_data($query) {
}
/**
- * Update a row in the database.
+ * Update the database.
*
* @note Altering the DB invalidates all queries in {@link $DB_QUERY_CACHE}.
*
@@ -488,18 +483,12 @@ function insert_data($query) {
* @access private
*/
function update_data($query) {
- global $DB_QUERY_CACHE;
elgg_log("DB query $query", 'NOTICE');
$dblink = get_db_link('write');
- // Invalidate query cache
- if ($DB_QUERY_CACHE) {
- /* @var ElggStaticVariableCache $DB_QUERY_CACHE */
- $DB_QUERY_CACHE->clear();
- elgg_log("Query cache invalidated", 'NOTICE');
- }
+ _elgg_invalidate_query_cache();
if (execute_query("$query", $dblink)) {
return TRUE;
@@ -509,7 +498,7 @@ function update_data($query) {
}
/**
- * Remove a row from the database.
+ * Remove data from the database.
*
* @note Altering the DB invalidates all queries in {@link $DB_QUERY_CACHE}.
*
@@ -519,18 +508,12 @@ function update_data($query) {
* @access private
*/
function delete_data($query) {
- global $DB_QUERY_CACHE;
elgg_log("DB query $query", 'NOTICE');
$dblink = get_db_link('write');
- // Invalidate query cache
- if ($DB_QUERY_CACHE) {
- /* @var ElggStaticVariableCache $DB_QUERY_CACHE */
- $DB_QUERY_CACHE->clear();
- elgg_log("Query cache invalidated", 'NOTICE');
- }
+ _elgg_invalidate_query_cache();
if (execute_query("$query", $dblink)) {
return mysql_affected_rows($dblink);
@@ -539,6 +522,22 @@ function delete_data($query) {
return FALSE;
}
+/**
+ * Invalidate the query cache
+ *
+ * @access private
+ */
+function _elgg_invalidate_query_cache() {
+ global $DB_QUERY_CACHE;
+ if ($DB_QUERY_CACHE instanceof ElggLRUCache) {
+ $DB_QUERY_CACHE->clear();
+ elgg_log("Query cache invalidated", 'NOTICE');
+ } elseif ($DB_QUERY_CACHE) {
+ // In case someone sets the cache to an array and primes it with data
+ $DB_QUERY_CACHE = array();
+ elgg_log("Query cache invalidated", 'NOTICE');
+ }
+}
/**
* Return tables matching the database prefix {@link $CONFIG->dbprefix}% in the currently
@@ -669,7 +668,7 @@ function run_sql_script($scriptlocation) {
/**
* Format a query string for logging
- *
+ *
* @param string $query Query string
* @return string
* @access private
diff --git a/engine/lib/deprecated-1.8.php b/engine/lib/deprecated-1.8.php
index 2b4ffcc4f..6aa42a81d 100644
--- a/engine/lib/deprecated-1.8.php
+++ b/engine/lib/deprecated-1.8.php
@@ -4772,3 +4772,47 @@ function default_page_handler($page, $handler) {
return FALSE;
}
+
+/**
+ * Invalidate this class's entry in the cache.
+ *
+ * @param int $guid The entity guid
+ *
+ * @return void
+ * @access private
+ * @deprecated 1.8
+ */
+function invalidate_cache_for_entity($guid) {
+ elgg_deprecated_notice('invalidate_cache_for_entity() is a private function and should not be used.', 1.8);
+ _elgg_invalidate_cache_for_entity($guid);
+}
+
+/**
+ * Cache an entity.
+ *
+ * Stores an entity in $ENTITY_CACHE;
+ *
+ * @param ElggEntity $entity Entity to cache
+ *
+ * @return void
+ * @access private
+ * @deprecated 1.8
+ */
+function cache_entity(ElggEntity $entity) {
+ elgg_deprecated_notice('cache_entity() is a private function and should not be used.', 1.8);
+ _elgg_cache_entity($entity);
+}
+
+/**
+ * Retrieve a entity from the cache.
+ *
+ * @param int $guid The guid
+ *
+ * @return ElggEntity|bool false if entity not cached, or not fully loaded
+ * @access private
+ * @deprecated 1.8
+ */
+function retrieve_cached_entity($guid) {
+ elgg_deprecated_notice('retrieve_cached_entity() is a private function and should not be used.', 1.8);
+ return _elgg_retrieve_cached_entity($guid);
+}
diff --git a/engine/lib/elgglib.php b/engine/lib/elgglib.php
index 74b70f9fb..34111c69d 100644
--- a/engine/lib/elgglib.php
+++ b/engine/lib/elgglib.php
@@ -93,10 +93,17 @@ function elgg_register_library($name, $location) {
* @return void
* @throws InvalidParameterException
* @since 1.8.0
+ * @todo return boolean in 1.9 to indicate whether the library has been loaded
*/
function elgg_load_library($name) {
global $CONFIG;
+ static $loaded_libraries = array();
+
+ if (in_array($name, $loaded_libraries)) {
+ return;
+ }
+
if (!isset($CONFIG->libraries)) {
$CONFIG->libraries = array();
}
@@ -113,6 +120,8 @@ function elgg_load_library($name) {
);
throw new InvalidParameterException($error);
}
+
+ $loaded_libraries[] = $name;
}
/**
@@ -128,7 +137,7 @@ function elgg_load_library($name) {
* @throws SecurityException
*/
function forward($location = "", $reason = 'system') {
- if (!headers_sent()) {
+ if (!headers_sent($file, $line)) {
if ($location === REFERER) {
$location = $_SERVER['HTTP_REFERER'];
}
@@ -147,7 +156,7 @@ function forward($location = "", $reason = 'system') {
exit;
}
} else {
- throw new SecurityException(elgg_echo('SecurityException:ForwardFailedToRedirect'));
+ throw new SecurityException(elgg_echo('SecurityException:ForwardFailedToRedirect', array($file, $line)));
}
}
@@ -737,7 +746,7 @@ function elgg_unregister_event_handler($event, $object_type, $callback) {
* @tip When referring to events, the preferred syntax is "event, type".
*
* @internal Only rarely should events be changed, added, or removed in core.
- * When making changes to events, be sure to first create a ticket in trac.
+ * When making changes to events, be sure to first create a ticket on Github.
*
* @internal @tip Think of $object_type as the primary namespace element, and
* $event as the secondary namespace.
@@ -1185,6 +1194,11 @@ function elgg_dump($value, $to_screen = TRUE, $level = 'NOTICE') {
$to_screen = FALSE;
}
+ // Do not want to write to JS or CSS pages
+ if (elgg_in_context('js') || elgg_in_context('css')) {
+ $to_screen = FALSE;
+ }
+
if ($to_screen == TRUE) {
echo '<pre>';
print_r($value);
@@ -1336,7 +1350,7 @@ function full_url() {
"" : (":" . $_SERVER["SERVER_PORT"]);
// This is here to prevent XSS in poorly written browsers used by 80% of the population.
- // {@trac [5813]}
+ // https://github.com/Elgg/Elgg/commit/0c947e80f512cb0a482b1864fd0a6965c8a0cd4a
$quotes = array('\'', '"');
$encoded = array('%27', '%22');
@@ -1383,8 +1397,8 @@ function elgg_http_build_url(array $parts, $html_encode = TRUE) {
* add tokens to the action. The form view automatically handles
* tokens.
*
- * @param string $url Full action URL
- * @param bool $html_encode HTML encode the url? (default: false)
+ * @param string $url Full action URL
+ * @param bool $html_encode HTML encode the url? (default: false)
*
* @return string URL with action tokens
* @since 1.7.0
@@ -1446,7 +1460,7 @@ function elgg_http_remove_url_query_element($url, $element) {
* Adds an element or elements to a URL's query string.
*
* @param string $url The URL
- * @param array $elements Key/value pairs to add to the URL
+ * @param array $elements Key/value pairs to add to the URL
*
* @return string The new URL with the query strings added
* @since 1.7.0
@@ -2233,6 +2247,9 @@ function elgg_api_test($hook, $type, $value, $params) {
/**#@+
* Controls access levels on ElggEntity entities, metadata, and annotations.
*
+ * @warning ACCESS_DEFAULT is a place holder for the input/access view. Do not
+ * use it when saving an entity.
+ *
* @var int
*/
define('ACCESS_DEFAULT', -1);
diff --git a/engine/lib/entities.php b/engine/lib/entities.php
index 156eec040..4fcf1c657 100644
--- a/engine/lib/entities.php
+++ b/engine/lib/entities.php
@@ -17,6 +17,15 @@ global $ENTITY_CACHE;
$ENTITY_CACHE = array();
/**
+ * GUIDs of entities banned from the entity cache (during this request)
+ *
+ * @global array $ENTITY_CACHE_DISABLED_GUIDS
+ * @access private
+ */
+global $ENTITY_CACHE_DISABLED_GUIDS;
+$ENTITY_CACHE_DISABLED_GUIDS = array();
+
+/**
* Cache subtypes and related class names.
*
* @global array|null $SUBTYPE_CACHE array once populated from DB, initially null
@@ -26,14 +35,42 @@ global $SUBTYPE_CACHE;
$SUBTYPE_CACHE = null;
/**
+ * Remove this entity from the entity cache and make sure it is not re-added
+ *
+ * @param int $guid The entity guid
+ *
+ * @access private
+ * @todo this is a workaround until #5604 can be implemented
+ */
+function _elgg_disable_caching_for_entity($guid) {
+ global $ENTITY_CACHE_DISABLED_GUIDS;
+
+ _elgg_invalidate_cache_for_entity($guid);
+ $ENTITY_CACHE_DISABLED_GUIDS[$guid] = true;
+}
+
+/**
+ * Allow this entity to be stored in the entity cache
+ *
+ * @param int $guid The entity guid
+ *
+ * @access private
+ */
+function _elgg_enable_caching_for_entity($guid) {
+ global $ENTITY_CACHE_DISABLED_GUIDS;
+
+ unset($ENTITY_CACHE_DISABLED_GUIDS[$guid]);
+}
+
+/**
* Invalidate this class's entry in the cache.
*
* @param int $guid The entity guid
*
- * @return null
+ * @return void
* @access private
*/
-function invalidate_cache_for_entity($guid) {
+function _elgg_invalidate_cache_for_entity($guid) {
global $ENTITY_CACHE;
$guid = (int)$guid;
@@ -50,14 +87,14 @@ function invalidate_cache_for_entity($guid) {
*
* @param ElggEntity $entity Entity to cache
*
- * @return null
- * @see retrieve_cached_entity()
- * @see invalidate_cache_for_entity()
+ * @return void
+ * @see _elgg_retrieve_cached_entity()
+ * @see _elgg_invalidate_cache_for_entity()
* @access private
- * TODO(evan): Use an ElggCache object
+ * @todo Use an ElggCache object
*/
-function cache_entity(ElggEntity $entity) {
- global $ENTITY_CACHE;
+function _elgg_cache_entity(ElggEntity $entity) {
+ global $ENTITY_CACHE, $ENTITY_CACHE_DISABLED_GUIDS;
// Don't cache non-plugin entities while access control is off, otherwise they could be
// exposed to users who shouldn't see them when control is re-enabled.
@@ -65,8 +102,13 @@ function cache_entity(ElggEntity $entity) {
return;
}
+ $guid = $entity->getGUID();
+ if (isset($ENTITY_CACHE_DISABLED_GUIDS[$guid])) {
+ return;
+ }
+
// Don't store too many or we'll have memory problems
- // TODO(evan): Pick a less arbitrary limit
+ // @todo Pick a less arbitrary limit
if (count($ENTITY_CACHE) > 256) {
$random_guid = array_rand($ENTITY_CACHE);
@@ -79,7 +121,7 @@ function cache_entity(ElggEntity $entity) {
elgg_get_metadata_cache()->clear($random_guid);
}
- $ENTITY_CACHE[$entity->guid] = $entity;
+ $ENTITY_CACHE[$guid] = $entity;
}
/**
@@ -88,11 +130,11 @@ function cache_entity(ElggEntity $entity) {
* @param int $guid The guid
*
* @return ElggEntity|bool false if entity not cached, or not fully loaded
- * @see cache_entity()
- * @see invalidate_cache_for_entity()
+ * @see _elgg_cache_entity()
+ * @see _elgg_invalidate_cache_for_entity()
* @access private
*/
-function retrieve_cached_entity($guid) {
+function _elgg_retrieve_cached_entity($guid) {
global $ENTITY_CACHE;
if (isset($ENTITY_CACHE[$guid])) {
@@ -105,31 +147,6 @@ function retrieve_cached_entity($guid) {
}
/**
- * As retrieve_cached_entity, but returns the result as a stdClass
- * (compatible with load functions that expect a database row.)
- *
- * @param int $guid The guid
- *
- * @return mixed
- * @todo unused
- * @access private
- */
-function retrieve_cached_entity_row($guid) {
- $obj = retrieve_cached_entity($guid);
- if ($obj) {
- $tmp = new stdClass;
-
- foreach ($obj as $k => $v) {
- $tmp->$k = $v;
- }
-
- return $tmp;
- }
-
- return false;
-}
-
-/**
* Return the id for a given subtype.
*
* ElggEntity objects have a type and a subtype. Subtypes
@@ -432,7 +449,7 @@ function update_subtype($type, $subtype, $class = '') {
* @param int $time_created The time creation timestamp
*
* @return bool
- * @link http://docs.elgg.org/DataModel/Entities
+ * @throws InvalidParameterException
* @access private
*/
function update_entity($guid, $owner_guid, $access_id, $container_guid = null, $time_created = null) {
@@ -455,6 +472,10 @@ function update_entity($guid, $owner_guid, $access_id, $container_guid = null, $
$time_created = (int) $time_created;
}
+ if ($access_id == ACCESS_DEFAULT) {
+ throw new InvalidParameterException('ACCESS_DEFAULT is not a valid access level. See its documentation in elgglib.h');
+ }
+
if ($entity && $entity->canEdit()) {
if (elgg_trigger_event('update', $entity->type, $entity)) {
$ret = update_data("UPDATE {$CONFIG->dbprefix}entities
@@ -581,7 +602,6 @@ $container_guid = 0) {
$type = sanitise_string($type);
$subtype_id = add_subtype($type, $subtype);
$owner_guid = (int)$owner_guid;
- $access_id = (int)$access_id;
$time = time();
if ($site_guid == 0) {
$site_guid = $CONFIG->site_guid;
@@ -590,6 +610,10 @@ $container_guid = 0) {
if ($container_guid == 0) {
$container_guid = $owner_guid;
}
+ $access_id = (int)$access_id;
+ if ($access_id == ACCESS_DEFAULT) {
+ throw new InvalidParameterException('ACCESS_DEFAULT is not a valid access level. See its documentation in elgglib.h');
+ }
$user_guid = elgg_get_logged_in_user_guid();
if (!can_write_to_container($user_guid, $owner_guid, $type, $subtype)) {
@@ -737,7 +761,7 @@ function get_entity($guid) {
// @todo We need a single Memcache instance with a shared pool of namespace wrappers. This function would pull an instance from the pool.
static $shared_cache;
- // We could also use: if (!(int) $guid) { return FALSE },
+ // We could also use: if (!(int) $guid) { return FALSE },
// but that evaluates to a false positive for $guid = TRUE.
// This is a bit slower, but more thorough.
if (!is_numeric($guid) || $guid === 0 || $guid === '0') {
@@ -745,7 +769,7 @@ function get_entity($guid) {
}
// Check local cache first
- $new_entity = retrieve_cached_entity($guid);
+ $new_entity = _elgg_retrieve_cached_entity($guid);
if ($new_entity) {
return $new_entity;
}
@@ -767,7 +791,7 @@ function get_entity($guid) {
if ($shared_cache) {
$cached_entity = $shared_cache->load($guid);
- // @todo store ACLs in memcache http://trac.elgg.org/ticket/3018#comment:3
+ // @todo store ACLs in memcache https://github.com/elgg/elgg/issues/3018#issuecomment-13662617
if ($cached_entity) {
// @todo use ACL and cached entity access_id to determine if user can see it
return $cached_entity;
@@ -782,7 +806,7 @@ function get_entity($guid) {
}
if ($new_entity) {
- cache_entity($new_entity);
+ _elgg_cache_entity($new_entity);
}
return $new_entity;
}
@@ -909,6 +933,8 @@ function elgg_get_entities(array $options = array()) {
'joins' => array(),
'callback' => 'entity_row_to_elggstar',
+
+ '__ElggBatch' => null,
);
$options = array_merge($defaults, $options);
@@ -1026,7 +1052,7 @@ function elgg_get_entities(array $options = array()) {
}
if ($options['callback'] === 'entity_row_to_elggstar') {
- $dt = _elgg_fetch_entities_from_sql($query);
+ $dt = _elgg_fetch_entities_from_sql($query, $options['__ElggBatch']);
} else {
$dt = get_data($query, $options['callback']);
}
@@ -1037,7 +1063,7 @@ function elgg_get_entities(array $options = array()) {
foreach ($dt as $item) {
// A custom callback could result in items that aren't ElggEntity's, so check for them
if ($item instanceof ElggEntity) {
- cache_entity($item);
+ _elgg_cache_entity($item);
// plugins usually have only settings
if (!$item instanceof ElggPlugin) {
$guids[] = $item->guid;
@@ -1061,13 +1087,14 @@ function elgg_get_entities(array $options = array()) {
/**
* Return entities from an SQL query generated by elgg_get_entities.
*
- * @param string $sql
+ * @param string $sql
+ * @param ElggBatch $batch
* @return ElggEntity[]
*
* @access private
* @throws LogicException
*/
-function _elgg_fetch_entities_from_sql($sql) {
+function _elgg_fetch_entities_from_sql($sql, ElggBatch $batch = null) {
static $plugin_subtype;
if (null === $plugin_subtype) {
$plugin_subtype = get_subtype_id('object', 'plugin');
@@ -1102,7 +1129,7 @@ function _elgg_fetch_entities_from_sql($sql) {
if (empty($row->guid) || empty($row->type)) {
throw new LogicException('Entity row missing guid or type');
}
- if ($entity = retrieve_cached_entity($row->guid)) {
+ if ($entity = _elgg_retrieve_cached_entity($row->guid)) {
$rows[$i] = $entity;
continue;
}
@@ -1144,6 +1171,11 @@ function _elgg_fetch_entities_from_sql($sql) {
} catch (IncompleteEntityException $e) {
// don't let incomplete entities throw fatal errors
unset($rows[$i]);
+
+ // report incompletes to the batch process that spawned this query
+ if ($batch) {
+ $batch->reportIncompleteEntity($row);
+ }
}
}
}
@@ -1441,8 +1473,10 @@ function elgg_list_entities(array $options = array(), $getter = 'elgg_get_entiti
global $autofeed;
$autofeed = true;
+ $offset_key = isset($options['offset_key']) ? $options['offset_key'] : 'offset';
+
$defaults = array(
- 'offset' => (int) max(get_input('offset', 0), 0),
+ 'offset' => (int) max(get_input($offset_key, 0), 0),
'limit' => (int) max(get_input('limit', 10), 0),
'full_view' => TRUE,
'list_type_toggle' => FALSE,
@@ -1628,7 +1662,7 @@ function disable_entity($guid, $reason = "", $recursive = true) {
$entity->disableMetadata();
$entity->disableAnnotations();
- invalidate_cache_for_entity($guid);
+ _elgg_invalidate_cache_for_entity($guid);
$res = update_data("UPDATE {$CONFIG->dbprefix}entities
SET enabled = 'no'
@@ -1644,8 +1678,8 @@ function disable_entity($guid, $reason = "", $recursive = true) {
/**
* Enable an entity.
*
- * @warning In order to enable an entity using ElggEntity::enable(),
- * you must first use {@link access_show_hidden_entities()}.
+ * @warning In order to enable an entity, you must first use
+ * {@link access_show_hidden_entities()}.
*
* @param int $guid GUID of entity to enable
* @param bool $recursive Recursively enable all entities disabled with the entity?
@@ -1726,7 +1760,7 @@ function delete_entity($guid, $recursive = true) {
// delete cache
if (isset($ENTITY_CACHE[$guid])) {
- invalidate_cache_for_entity($guid);
+ _elgg_invalidate_cache_for_entity($guid);
}
// If memcache is available then delete this entry from the cache
@@ -1773,6 +1807,10 @@ function delete_entity($guid, $recursive = true) {
elgg_set_ignore_access($ia);
}
+ $entity_disable_override = access_get_show_hidden_status();
+ access_show_hidden_entities(true);
+ $ia = elgg_set_ignore_access(true);
+
// Now delete the entity itself
$entity->deleteMetadata();
$entity->deleteOwnedMetadata();
@@ -1780,6 +1818,9 @@ function delete_entity($guid, $recursive = true) {
$entity->deleteOwnedAnnotations();
$entity->deleteRelationships();
+ access_show_hidden_entities($entity_disable_override);
+ elgg_set_ignore_access($ia);
+
elgg_delete_river(array('subject_guid' => $guid));
elgg_delete_river(array('object_guid' => $guid));
remove_all_private_settings($guid);
@@ -2087,7 +2128,7 @@ function can_edit_entity_metadata($entity_guid, $user_guid = 0, $metadata = null
$return = null;
- if ($metadata->owner_guid == 0) {
+ if ($metadata && ($metadata->owner_guid == 0)) {
$return = true;
}
if (is_null($return)) {
@@ -2488,11 +2529,18 @@ function update_entity_last_action($guid, $posted = NULL) {
function entities_gc() {
global $CONFIG;
- $tables = array ('sites_entity', 'objects_entity', 'groups_entity', 'users_entity');
+ $tables = array(
+ 'site' => 'sites_entity',
+ 'object' => 'objects_entity',
+ 'group' => 'groups_entity',
+ 'user' => 'users_entity'
+ );
- foreach ($tables as $table) {
- delete_data("DELETE from {$CONFIG->dbprefix}{$table}
- where guid NOT IN (SELECT guid from {$CONFIG->dbprefix}entities)");
+ foreach ($tables as $type => $table) {
+ delete_data("DELETE FROM {$CONFIG->dbprefix}{$table}
+ WHERE guid NOT IN (SELECT guid FROM {$CONFIG->dbprefix}entities)");
+ delete_data("DELETE FROM {$CONFIG->dbprefix}entities
+ WHERE type = '$type' AND guid NOT IN (SELECT guid FROM {$CONFIG->dbprefix}{$table})");
}
}
diff --git a/engine/lib/extender.php b/engine/lib/extender.php
index 8756e051b..8323bd3ce 100644
--- a/engine/lib/extender.php
+++ b/engine/lib/extender.php
@@ -126,14 +126,20 @@ function import_extender_plugin_hook($hook, $entity_type, $returnvalue, $params)
* @return bool
*/
function can_edit_extender($extender_id, $type, $user_guid = 0) {
- if (!elgg_is_logged_in()) {
- return false;
+ // @todo Since Elgg 1.0, Elgg has returned false from can_edit_extender()
+ // if no user was logged in. This breaks the access override. This is a
+ // temporary work around. This function needs to be rewritten in Elgg 1.9
+ if (!elgg_check_access_overrides($user_guid)) {
+ if (!elgg_is_logged_in()) {
+ return false;
+ }
}
$user_guid = (int)$user_guid;
- $user = get_entity($user_guid);
+ $user = get_user($user_guid);
if (!$user) {
$user = elgg_get_logged_in_user_entity();
+ $user_guid = elgg_get_logged_in_user_guid();
}
$functionname = "elgg_get_{$type}_from_id";
@@ -149,16 +155,16 @@ function can_edit_extender($extender_id, $type, $user_guid = 0) {
/* @var ElggExtender $extender */
// If the owner is the specified user, great! They can edit.
- if ($extender->getOwnerGUID() == $user->getGUID()) {
+ if ($extender->getOwnerGUID() == $user_guid) {
return true;
}
// If the user can edit the entity this is attached to, great! They can edit.
- if (can_edit_entity($extender->entity_guid, $user->getGUID())) {
+ if (can_edit_entity($extender->entity_guid, $user_guid)) {
return true;
}
- // Trigger plugin hooks
+ // Trigger plugin hook - note that $user may be null
$params = array('entity' => $extender->getEntity(), 'user' => $user);
return elgg_trigger_plugin_hook('permissions_check', $type, $params, false);
}
diff --git a/engine/lib/group.php b/engine/lib/group.php
index 624029d98..6ded8a825 100644
--- a/engine/lib/group.php
+++ b/engine/lib/group.php
@@ -240,9 +240,11 @@ function leave_group($group_guid, $user_guid) {
*/
function get_users_membership($user_guid) {
$options = array(
+ 'type' => 'group',
'relationship' => 'member',
'relationship_guid' => $user_guid,
- 'inverse_relationship' => FALSE
+ 'inverse_relationship' => false,
+ 'limit' => false,
);
return elgg_get_entities_from_relationship($options);
}
diff --git a/engine/lib/input.php b/engine/lib/input.php
index 2d9bae4dd..80b0b8766 100644
--- a/engine/lib/input.php
+++ b/engine/lib/input.php
@@ -60,8 +60,8 @@ function get_input($variable, $default = NULL, $filter_result = TRUE) {
*
* Note: this function does not handle nested arrays (ex: form input of param[m][n])
*
- * @param string $variable The name of the variable
- * @param string $value The value of the variable
+ * @param string $variable The name of the variable
+ * @param string|string[] $value The value of the variable
*
* @return void
*/
diff --git a/engine/lib/languages.php b/engine/lib/languages.php
index 17db14d98..61ba91ddb 100644
--- a/engine/lib/languages.php
+++ b/engine/lib/languages.php
@@ -139,6 +139,9 @@ function get_language() {
return false;
}
+/**
+ * @access private
+ */
function _elgg_load_translations() {
global $CONFIG;
diff --git a/engine/lib/location.php b/engine/lib/location.php
index b319bb3bb..1534c7d7b 100644
--- a/engine/lib/location.php
+++ b/engine/lib/location.php
@@ -139,7 +139,7 @@ function elgg_get_entities_from_location(array $options = array()) {
/**
* Returns a viewable list of entities from location
*
- * @param array $options
+ * @param array $options Options array
*
* @see elgg_list_entities()
* @see elgg_get_entities_from_location()
diff --git a/engine/lib/metadata.php b/engine/lib/metadata.php
index 96d446060..fdb1b85f6 100644
--- a/engine/lib/metadata.php
+++ b/engine/lib/metadata.php
@@ -191,19 +191,19 @@ function update_metadata($id, $name, $value, $value_type, $owner_guid, $access_i
}
// Add the metastring
- $value = add_metastring($value);
- if (!$value) {
+ $value_id = add_metastring($value);
+ if (!$value_id) {
return false;
}
- $name = add_metastring($name);
- if (!$name) {
+ $name_id = add_metastring($name);
+ if (!$name_id) {
return false;
}
// If ok then add it
$query = "UPDATE {$CONFIG->dbprefix}metadata"
- . " set name_id='$name', value_id='$value', value_type='$value_type', access_id=$access_id,"
+ . " set name_id='$name_id', value_id='$value_id', value_type='$value_type', access_id=$access_id,"
. " owner_guid=$owner_guid where id=$id";
$result = update_data($query);
@@ -300,21 +300,22 @@ function elgg_get_metadata(array $options = array()) {
* This requires at least one constraint: metadata_owner_guid(s),
* metadata_name(s), metadata_value(s), or guid(s) must be set.
*
- * @warning This returns null on no ops.
- *
* @param array $options An options array. {@see elgg_get_metadata()}
- * @return mixed Null if the metadata name is invalid. Bool on success or fail.
+ * @return bool|null true on success, false on failure, null if no metadata to delete.
* @since 1.8.0
*/
function elgg_delete_metadata(array $options) {
if (!elgg_is_valid_options_for_batch_operation($options, 'metadata')) {
return false;
}
+ $options['metastring_type'] = 'metadata';
+ $result = elgg_batch_metastring_based_objects($options, 'elgg_batch_delete_callback', false);
+ // This moved last in case an object's constructor sets metadata. Currently the batch
+ // delete process has to create the entity to delete its metadata. See #5214
elgg_get_metadata_cache()->invalidateByOptions('delete', $options);
- $options['metastring_type'] = 'metadata';
- return elgg_batch_metastring_based_objects($options, 'elgg_batch_delete_callback', false);
+ return $result;
}
/**
@@ -322,10 +323,8 @@ function elgg_delete_metadata(array $options) {
*
* @warning Unlike elgg_get_metadata() this will not accept an empty options array!
*
- * @warning This returns null on no ops.
- *
* @param array $options An options array. {@See elgg_get_metadata()}
- * @return mixed
+ * @return bool|null true on success, false on failure, null if no metadata disabled.
* @since 1.8.0
*/
function elgg_disable_metadata(array $options) {
@@ -334,9 +333,13 @@ function elgg_disable_metadata(array $options) {
}
elgg_get_metadata_cache()->invalidateByOptions('disable', $options);
+
+ // if we can see hidden (disabled) we need to use the offset
+ // otherwise we risk an infinite loop if there are more than 50
+ $inc_offset = access_get_show_hidden_status();
$options['metastring_type'] = 'metadata';
- return elgg_batch_metastring_based_objects($options, 'elgg_batch_disable_callback', false);
+ return elgg_batch_metastring_based_objects($options, 'elgg_batch_disable_callback', $inc_offset);
}
/**
@@ -344,10 +347,11 @@ function elgg_disable_metadata(array $options) {
*
* @warning Unlike elgg_get_metadata() this will not accept an empty options array!
*
- * @warning This returns null on no ops.
+ * @warning In order to enable metadata, you must first use
+ * {@link access_show_hidden_entities()}.
*
* @param array $options An options array. {@See elgg_get_metadata()}
- * @return mixed
+ * @return bool|null true on success, false on failure, null if no metadata enabled.
* @since 1.8.0
*/
function elgg_enable_metadata(array $options) {
@@ -402,9 +406,11 @@ function elgg_enable_metadata(array $options) {
* 'operand' => '=',
* 'case_sensitive' => TRUE
* )
- * Currently if multiple values are sent via
+ * Currently if multiple values are sent via
* an array (value => array('value1', 'value2')
* the pair's operand will be forced to "IN".
+ * If passing "IN" as the operand and a string as the value,
+ * the value must be a properly quoted and escaped string.
*
* metadata_name_value_pairs_operator => NULL|STR The operator to use for combining
* (name = value) OPERATOR (name = value); default AND
@@ -616,6 +622,8 @@ $owner_guids = NULL) {
// if the operand is IN don't quote it because quoting should be done already.
if (is_numeric($pair['value'])) {
$value = sanitise_string($pair['value']);
+ } else if (is_bool($pair['value'])) {
+ $value = (int) $pair['value'];
} else if (is_array($pair['value'])) {
$values_array = array();
@@ -917,8 +925,8 @@ function elgg_get_metadata_cache() {
* Invalidate the metadata cache based on options passed to various *_metadata functions
*
* @param string $action Action performed on metadata. "delete", "disable", or "enable"
- *
- * @param array $options Options passed to elgg_(delete|disable|enable)_metadata
+ * @param array $options Options passed to elgg_(delete|disable|enable)_metadata
+ * @return void
*/
function elgg_invalidate_metadata_cache($action, array $options) {
// remove as little as possible, optimizing for common cases
diff --git a/engine/lib/metastrings.php b/engine/lib/metastrings.php
index f49b4a163..57d876c06 100644
--- a/engine/lib/metastrings.php
+++ b/engine/lib/metastrings.php
@@ -421,9 +421,11 @@ function elgg_get_metastring_based_objects($options) {
if ($metastring_clauses) {
$wheres = array_merge($wheres, $metastring_clauses['wheres']);
$joins = array_merge($joins, $metastring_clauses['joins']);
+ } else {
+ $wheres[] = get_access_sql_suffix('n_table');
}
- if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE) {
+ if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE && !$options['count']) {
$selects = array_unique($selects);
// evalutate selects
$select_str = '';
@@ -434,6 +436,9 @@ function elgg_get_metastring_based_objects($options) {
}
$query = "SELECT DISTINCT n_table.*{$select_str} FROM {$db_prefix}$type n_table";
+ } elseif ($options['count']) {
+ // count is over the entities
+ $query = "SELECT count(DISTINCT e.guid) as calculation FROM {$db_prefix}$type n_table";
} else {
$query = "SELECT {$options['metastring_calculation']}(v.string) as calculation FROM {$db_prefix}$type n_table";
}
@@ -462,7 +467,7 @@ function elgg_get_metastring_based_objects($options) {
$defaults['order_by']);
}
- if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE) {
+ if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE && !$options['count']) {
if (isset($options['group_by'])) {
$options['group_by'] = sanitise_string($options['group_by']);
$query .= " GROUP BY {$options['group_by']}";
@@ -510,7 +515,7 @@ function elgg_get_metastring_sql($table, $names = null, $values = null,
&& !$ids
&& (!$pairs && $pairs !== 0)) {
- return '';
+ return array();
}
$db_prefix = elgg_get_config('dbprefix');
@@ -520,8 +525,6 @@ function elgg_get_metastring_sql($table, $names = null, $values = null,
// only supported on values.
$binary = ($case_sensitive) ? ' BINARY ' : '';
- $access = get_access_sql_suffix($table);
-
$return = array (
'joins' => array (),
'wheres' => array()
@@ -586,13 +589,15 @@ function elgg_get_metastring_sql($table, $names = null, $values = null,
}
if ($names_where && $values_where) {
- $wheres[] = "($names_where AND $values_where AND $access)";
+ $wheres[] = "($names_where AND $values_where)";
} elseif ($names_where) {
- $wheres[] = "($names_where AND $access)";
+ $wheres[] = $names_where;
} elseif ($values_where) {
- $wheres[] = "($values_where AND $access)";
+ $wheres[] = $values_where;
}
+ $wheres[] = get_access_sql_suffix($table);
+
if ($where = implode(' AND ', $wheres)) {
$return['wheres'][] = "($where)";
}
diff --git a/engine/lib/navigation.php b/engine/lib/navigation.php
index 118a7214c..ab9cc05e8 100644
--- a/engine/lib/navigation.php
+++ b/engine/lib/navigation.php
@@ -218,7 +218,7 @@ function elgg_push_breadcrumb($title, $link = NULL) {
}
// avoid key collisions.
- $CONFIG->breadcrumbs[] = array('title' => $title, 'link' => $link);
+ $CONFIG->breadcrumbs[] = array('title' => elgg_get_excerpt($title, 100), 'link' => $link);
}
/**
@@ -323,7 +323,8 @@ function elgg_site_menu_setup($hook, $type, $return, $params) {
}
if (!$selected) {
- // nothing selected, match name to context
+ // nothing selected, match name to context or match url
+ $current_url = current_page_url();
foreach ($return as $section_name => $section) {
foreach ($section as $key => $item) {
// only highlight internal links
@@ -332,6 +333,10 @@ function elgg_site_menu_setup($hook, $type, $return, $params) {
$return[$section_name][$key]->setSelected(true);
break 2;
}
+ if ($item->getHref() == $current_url) {
+ $return[$section_name][$key]->setSelected(true);
+ break 2;
+ }
}
}
}
diff --git a/engine/lib/opendd.php b/engine/lib/opendd.php
index f00ea6aab..7d635a295 100644
--- a/engine/lib/opendd.php
+++ b/engine/lib/opendd.php
@@ -7,6 +7,8 @@
* @version 0.4
*/
+// @codingStandardsIgnoreStart
+
/**
* Attempt to construct an ODD object out of a XmlElement or sub-elements.
*
@@ -103,3 +105,5 @@ function ODD_Import($xml) {
function ODD_Export(ODDDocument $document) {
return "$document";
}
+
+// @codingStandardsIgnoreEnd
diff --git a/engine/lib/output.php b/engine/lib/output.php
index da8e1ab86..6172a5c8d 100644
--- a/engine/lib/output.php
+++ b/engine/lib/output.php
@@ -13,28 +13,33 @@
* @param string $text The input string
*
* @return string The output string with formatted links
- **/
+ */
function parse_urls($text) {
+
+ // URI specification: http://www.ietf.org/rfc/rfc3986.txt
+ // This varies from the specification in the following ways:
+ // * Supports non-ascii characters
+ // * Does not allow parentheses and single quotes
+ // * Cuts off commas, exclamation points, and periods off as last character
+
// @todo this causes problems with <attr = "val">
// must be in <attr="val"> format (no space).
// By default htmlawed rewrites tags to this format.
// if PHP supported conditional negative lookbehinds we could use this:
// $r = preg_replace_callback('/(?<!=)(?<![ ])?(?<!["\'])((ht|f)tps?:\/\/[^\s\r\n\t<>"\'\!\(\),]+)/i',
- //
- // we can put , in the list of excluded char but need to keep . because of domain names.
- // it is removed in the callback.
- $r = preg_replace_callback('/(?<!=)(?<!["\'])((ht|f)tps?:\/\/[^\s\r\n\t<>"\'\!\(\),]+)/i',
+ $r = preg_replace_callback('/(?<![=\/"\'])((ht|f)tps?:\/\/[^\s\r\n\t<>"\']+)/i',
create_function(
'$matches',
'
$url = $matches[1];
- $period = \'\';
- if (substr($url, -1, 1) == \'.\') {
- $period = \'.\';
- $url = trim($url, \'.\');
+ $punc = "";
+ $last = substr($url, -1, 1);
+ if (in_array($last, array(".", "!", ",", "(", ")"))) {
+ $punc = $last;
+ $url = rtrim($url, ".!,()");
}
$urltext = str_replace("/", "/<wbr />", $url);
- return "<a href=\"$url\">$urltext</a>$period";
+ return "<a href=\"$url\" rel=\"nofollow\">$urltext</a>$punc";
'
), $text);
@@ -284,11 +289,9 @@ function elgg_get_friendly_title($title) {
return $result;
}
- // handle some special cases
- $title = str_replace('&amp;', 'and', $title);
- // quotes and angle brackets stored in the database as html encoded
- $title = htmlspecialchars_decode($title);
-
+ // titles are often stored HTML encoded
+ $title = html_entity_decode($title, ENT_QUOTES, 'UTF-8');
+
$title = ElggTranslit::urlize($title);
return $title;
diff --git a/engine/lib/pageowner.php b/engine/lib/pageowner.php
index 7e8e6e430..bd63d08c6 100644
--- a/engine/lib/pageowner.php
+++ b/engine/lib/pageowner.php
@@ -29,7 +29,9 @@ function elgg_get_page_owner_guid($guid = 0) {
// return guid of page owner entity
$guid = elgg_trigger_plugin_hook('page_owner', 'system', NULL, 0);
- $page_owner_guid = $guid;
+ if ($guid) {
+ $page_owner_guid = $guid;
+ }
return $guid;
}
diff --git a/engine/lib/plugins.php b/engine/lib/plugins.php
index f281b1416..d5d3db466 100644
--- a/engine/lib/plugins.php
+++ b/engine/lib/plugins.php
@@ -312,10 +312,10 @@ function elgg_is_active_plugin($plugin_id, $site_guid = null) {
*/
function elgg_load_plugins() {
$plugins_path = elgg_get_plugins_path();
- $start_flags = ELGG_PLUGIN_INCLUDE_START
- | ELGG_PLUGIN_REGISTER_VIEWS
- | ELGG_PLUGIN_REGISTER_LANGUAGES
- | ELGG_PLUGIN_REGISTER_CLASSES;
+ $start_flags = ELGG_PLUGIN_INCLUDE_START |
+ ELGG_PLUGIN_REGISTER_VIEWS |
+ ELGG_PLUGIN_REGISTER_LANGUAGES |
+ ELGG_PLUGIN_REGISTER_CLASSES;
if (!$plugins_path) {
return false;
@@ -865,7 +865,7 @@ function elgg_set_plugin_user_setting($name, $value, $user_guid = null, $plugin_
* Unsets a user-specific plugin setting
*
* @param string $name Name of the setting
- * @param int $user_guid Defaults to logged in user
+ * @param int $user_guid Defaults to logged in user
* @param string $plugin_id Defaults to contextual plugin name
*
* @return bool
@@ -1105,6 +1105,49 @@ function plugins_test($hook, $type, $value, $params) {
}
/**
+ * Checks on deactivate plugin event if disabling it won't create unmet dependencies and blocks disable in such case.
+ *
+ * @param string $event deactivate
+ * @param string $type plugin
+ * @param array $params Parameters array containing entry with ELggPlugin instance under 'plugin_entity' key
+ * @return bool false to block plugin deactivation action
+ *
+ * @access private
+ */
+function _plugins_deactivate_dependency_check($event, $type, $params) {
+ $plugin_id = $params['plugin_entity']->getManifest()->getPluginID();
+ $plugin_name = $params['plugin_entity']->getManifest()->getName();
+
+ $active_plugins = elgg_get_plugins();
+
+ $dependents = array();
+ foreach ($active_plugins as $plugin) {
+ $manifest = $plugin->getManifest();
+ $requires = $manifest->getRequires();
+
+ foreach ($requires as $required) {
+ if ($required['type'] == 'plugin' && $required['name'] == $plugin_id) {
+ // there are active dependents
+ $dependents[$manifest->getPluginID()] = $plugin;
+ }
+ }
+ }
+
+ if ($dependents) {
+ $list = '<ul>';
+ // construct error message and prevent disabling
+ foreach ($dependents as $dependent) {
+ $list .= '<li>' . $dependent->getManifest()->getName() . '</li>';
+ }
+ $list .= '</ul>';
+
+ register_error(elgg_echo('ElggPlugin:Dependencies:ActiveDependent', array($plugin_name, $list)));
+
+ return false;
+ }
+}
+
+/**
* Initialize the plugin system
* Listens to system init and registers actions
*
@@ -1115,6 +1158,10 @@ function plugin_init() {
run_function_once("plugin_run_once");
elgg_register_plugin_hook_handler('unit_test', 'system', 'plugins_test');
+
+ // note - plugins are booted by the time this handler is registered
+ // deactivation due to error may have already occurred
+ elgg_register_event_handler('deactivate', 'plugin', '_plugins_deactivate_dependency_check');
elgg_register_action("plugins/settings/save", '', 'admin');
elgg_register_action("plugins/usersettings/save");
diff --git a/engine/lib/relationships.php b/engine/lib/relationships.php
index c1a7cc080..b0cd627fc 100644
--- a/engine/lib/relationships.php
+++ b/engine/lib/relationships.php
@@ -109,7 +109,7 @@ function add_entity_relationship($guid_one, $relationship, $guid_two) {
* @param string $relationship The type of relationship
* @param int $guid_two The GUID of the entity the relationship is with
*
- * @return object|false Depending on success
+ * @return ElggRelationship|false Depending on success
*/
function check_entity_relationship($guid_one, $relationship, $guid_two) {
global $CONFIG;
@@ -123,7 +123,7 @@ function check_entity_relationship($guid_one, $relationship, $guid_two) {
AND relationship='$relationship'
AND guid_two=$guid_two limit 1";
- $row = get_data_row($query);
+ $row = row_to_elggrelationship(get_data_row($query));
if ($row) {
return $row;
}
@@ -363,7 +363,7 @@ $relationship_guid = NULL, $inverse_relationship = FALSE) {
/**
* Returns a viewable list of entities by relationship
*
- * @param array $options
+ * @param array $options Options array for retrieval of entities
*
* @see elgg_list_entities()
* @see elgg_get_entities_from_relationship()
diff --git a/engine/lib/river.php b/engine/lib/river.php
index f2ec1e101..e92040eb7 100644
--- a/engine/lib/river.php
+++ b/engine/lib/river.php
@@ -120,7 +120,7 @@ $posted = 0, $annotation_id = 0) {
* subtypes => STR|ARR Entity subtype string(s)
* type_subtype_pairs => ARR Array of type => subtype pairs where subtype
* can be an array of subtype strings
- *
+ *
* posted_time_lower => INT The lower bound on the time posted
* posted_time_upper => INT The upper bound on the time posted
*
@@ -380,10 +380,10 @@ function _elgg_prefetch_river_entities(array $river_items) {
// prefetch objects and subjects
$guids = array();
foreach ($river_items as $item) {
- if ($item->subject_guid && !retrieve_cached_entity($item->subject_guid)) {
+ if ($item->subject_guid && !_elgg_retrieve_cached_entity($item->subject_guid)) {
$guids[$item->subject_guid] = true;
}
- if ($item->object_guid && !retrieve_cached_entity($item->object_guid)) {
+ if ($item->object_guid && !_elgg_retrieve_cached_entity($item->object_guid)) {
$guids[$item->object_guid] = true;
}
}
@@ -402,7 +402,7 @@ function _elgg_prefetch_river_entities(array $river_items) {
$guids = array();
foreach ($river_items as $item) {
$object = $item->getObjectEntity();
- if ($object->container_guid && !retrieve_cached_entity($object->container_guid)) {
+ if ($object->container_guid && !_elgg_retrieve_cached_entity($object->container_guid)) {
$guids[$object->container_guid] = true;
}
}
@@ -434,8 +434,13 @@ function elgg_list_river(array $options = array()) {
'pagination' => TRUE,
'list_class' => 'elgg-list-river elgg-river', // @todo remove elgg-river in Elgg 1.9
);
-
+
$options = array_merge($defaults, $options);
+
+ if (!$options["limit"] && !$options["offset"]) {
+ // no need for pagination if listing is unlimited
+ $options["pagination"] = false;
+ }
$options['count'] = TRUE;
$count = elgg_get_river($options);
@@ -445,6 +450,7 @@ function elgg_list_river(array $options = array()) {
$options['count'] = $count;
$options['items'] = $items;
+
return elgg_view('page/components/list', $options);
}
diff --git a/engine/lib/sessions.php b/engine/lib/sessions.php
index a34c2045b..fb28e1e9a 100644
--- a/engine/lib/sessions.php
+++ b/engine/lib/sessions.php
@@ -87,6 +87,9 @@ function elgg_is_admin_logged_in() {
*/
function elgg_is_admin_user($user_guid) {
global $CONFIG;
+
+ $user_guid = (int)$user_guid;
+
// cannot use magic metadata here because of recursion
// must support the old way of getting admin from metadata
diff --git a/engine/lib/statistics.php b/engine/lib/statistics.php
index 0c9a3c945..4cb0bb0b8 100644
--- a/engine/lib/statistics.php
+++ b/engine/lib/statistics.php
@@ -95,13 +95,17 @@ function get_number_users($show_deactivated = false) {
* @return string
*/
function get_online_users() {
- $count = find_active_users(600, 10, 0, true);
- $objects = find_active_users(600, 10);
+ $limit = max(0, (int) get_input("limit", 10));
+ $offset = max(0, (int) get_input("offset", 0));
+
+ $count = find_active_users(600, $limit, $offset, true);
+ $objects = find_active_users(600, $limit, $offset);
if ($objects) {
return elgg_view_entity_list($objects, array(
'count' => $count,
- 'limit' => 10,
+ 'limit' => $limit,
+ 'offset' => $offset
));
}
return '';
diff --git a/engine/lib/upgrade.php b/engine/lib/upgrade.php
index d684af862..158ec9ec1 100644
--- a/engine/lib/upgrade.php
+++ b/engine/lib/upgrade.php
@@ -245,7 +245,7 @@ function version_upgrade() {
// No version number? Oh snap...this is an upgrade from a clean installation < 1.7.
// Run all upgrades without error reporting and hope for the best.
- // See http://trac.elgg.org/elgg/ticket/1432 for more.
+ // See https://github.com/elgg/elgg/issues/1432 for more.
$quiet = !$dbversion;
// Note: Database upgrades are deprecated as of 1.8. Use code upgrades. See #1433
@@ -354,16 +354,12 @@ function _elgg_upgrade_unlock() {
* @access private
*/
function _elgg_upgrade_is_locked() {
- global $CONFIG, $DB_QUERY_CACHE;
-
+ global $CONFIG;
+
$is_locked = count(get_data("show tables like '{$CONFIG->dbprefix}upgrade_lock'"));
-
- // Invalidate query cache
- if ($DB_QUERY_CACHE) {
- /* @var ElggStaticVariableCache $DB_QUERY_CACHE */
- $DB_QUERY_CACHE->clear();
- elgg_log("Query cache invalidated", 'NOTICE');
- }
-
+
+ // @todo why?
+ _elgg_invalidate_query_cache();
+
return $is_locked;
}
diff --git a/engine/lib/upgrades/2009102801.php b/engine/lib/upgrades/2009102801.php
index cab9a6835..3ad113fb2 100644
--- a/engine/lib/upgrades/2009102801.php
+++ b/engine/lib/upgrades/2009102801.php
@@ -203,14 +203,15 @@ function user_file_matrix($guid) {
return "$time_created/$user->guid/";
}
-global $DB_QUERY_CACHE, $DB_PROFILE, $ENTITY_CACHE;
+global $ENTITY_CACHE, $CONFIG;
/**
* Upgrade file locations
*/
$users = mysql_query("SELECT guid, username
FROM {$CONFIG->dbprefix}users_entity WHERE username != ''");
while ($user = mysql_fetch_object($users)) {
- $DB_QUERY_CACHE = $DB_PROFILE = $ENTITY_CACHE = array();
+ $ENTITY_CACHE = array();
+ _elgg_invalidate_query_cache();
$to = $CONFIG->dataroot . user_file_matrix($user->guid);
foreach (array('1_0', '1_1', '1_6') as $version) {
diff --git a/engine/lib/upgrades/2010033101.php b/engine/lib/upgrades/2010033101.php
index 0bffee001..4779295fd 100644
--- a/engine/lib/upgrades/2010033101.php
+++ b/engine/lib/upgrades/2010033101.php
@@ -1,7 +1,7 @@
<?php
/**
- * Conditional upgrade for UTF8 as described in http://trac.elgg.org/ticket/1928
+ * Conditional upgrade for UTF8 as described in https://github.com/elgg/elgg/issues/1928
*/
// get_version() returns the code version.
diff --git a/engine/lib/upgrades/2010061501.php b/engine/lib/upgrades/2010061501.php
index 9ff7d3102..744c28fd5 100644
--- a/engine/lib/upgrades/2010061501.php
+++ b/engine/lib/upgrades/2010061501.php
@@ -45,7 +45,7 @@ if ($dbversion < 2009100701) {
}
}
- global $DB_QUERY_CACHE, $DB_PROFILE, $ENTITY_CACHE;
+ global $ENTITY_CACHE;
/**
Upgrade file locations
@@ -60,7 +60,9 @@ if ($dbversion < 2009100701) {
$users = mysql_query("SELECT guid, username FROM {$CONFIG->dbprefix}users_entity
WHERE username != ''", $link);
while ($user = mysql_fetch_object($users)) {
- $DB_QUERY_CACHE = $DB_PROFILE = $ENTITY_CACHE = array();
+ $ENTITY_CACHE = array();
+ _elgg_invalidate_query_cache();
+
$to = $CONFIG->dataroot . user_file_matrix($user->guid);
foreach (array('1_0', '1_1', '1_6') as $version) {
diff --git a/engine/lib/upgrades/2010071001.php b/engine/lib/upgrades/2010071001.php
index 1b5d379d8..5594493a8 100644
--- a/engine/lib/upgrades/2010071001.php
+++ b/engine/lib/upgrades/2010071001.php
@@ -30,11 +30,12 @@ function user_file_matrix_2010071001($guid) {
$sizes = array('large', 'medium', 'small', 'tiny', 'master', 'topbar');
-global $DB_QUERY_CACHE, $DB_PROFILE, $ENTITY_CACHE, $CONFIG;
+global $ENTITY_CACHE, $CONFIG;
$users = mysql_query("SELECT guid, username FROM {$CONFIG->dbprefix}users_entity
WHERE username != ''");
while ($user = mysql_fetch_object($users)) {
- $DB_QUERY_CACHE = $DB_PROFILE = $ENTITY_CACHE = array();
+ $ENTITY_CACHE = array();
+ _elgg_invalidate_query_cache();
$user_directory = user_file_matrix_2010071001($user->guid);
if (!$user_directory) {
diff --git a/engine/lib/upgrades/2010071002.php b/engine/lib/upgrades/2010071002.php
index 30bd6538c..52aa15ef5 100644
--- a/engine/lib/upgrades/2010071002.php
+++ b/engine/lib/upgrades/2010071002.php
@@ -4,12 +4,13 @@
*/
// loop through all users checking collections and notifications
-global $DB_QUERY_CACHE, $DB_PROFILE, $ENTITY_CACHE, $CONFIG;
+global $ENTITY_CACHE, $CONFIG;
global $NOTIFICATION_HANDLERS;
$users = mysql_query("SELECT guid, username FROM {$CONFIG->dbprefix}users_entity
WHERE username != ''");
while ($user = mysql_fetch_object($users)) {
- $DB_QUERY_CACHE = $DB_PROFILE = $ENTITY_CACHE = array();
+ $ENTITY_CACHE = array();
+ _elgg_invalidate_query_cache();
$user = get_entity($user->guid);
foreach ($NOTIFICATION_HANDLERS as $method => $foo) {
diff --git a/engine/lib/upgrades/2011052801.php b/engine/lib/upgrades/2011052801.php
index 8084bc06c..b5a8e1018 100644
--- a/engine/lib/upgrades/2011052801.php
+++ b/engine/lib/upgrades/2011052801.php
@@ -2,7 +2,7 @@
/**
* Make sure all users have the relationship member_of_site
*/
-global $DB_QUERY_CACHE, $DB_PROFILE, $ENTITY_CACHE, $CONFIG;
+global $ENTITY_CACHE;
$db_prefix = get_config('dbprefix');
$limit = 100;
@@ -17,7 +17,8 @@ $q = "SELECT e.* FROM {$db_prefix}entities e
$users = get_data($q);
while ($users) {
- $DB_QUERY_CACHE = $DB_PROFILE = $ENTITY_CACHE = array();
+ $ENTITY_CACHE = array();
+ _elgg_invalidate_query_cache();
// do manually to not trigger any events because these aren't new users.
foreach ($users as $user) {
diff --git a/engine/lib/upgrades/2012041801-1.8.3-multiple_user_tokens-852225f7fd89f6c5.php b/engine/lib/upgrades/2012041801-1.8.3-multiple_user_tokens-852225f7fd89f6c5.php
index 07732f261..780038c32 100644
--- a/engine/lib/upgrades/2012041801-1.8.3-multiple_user_tokens-852225f7fd89f6c5.php
+++ b/engine/lib/upgrades/2012041801-1.8.3-multiple_user_tokens-852225f7fd89f6c5.php
@@ -3,7 +3,7 @@
* Elgg 1.8.3 upgrade 2012041801
* multiple_user_tokens
*
- * Fixes http://trac.elgg.org/ticket/4291
+ * Fixes https://github.com/elgg/elgg/issues/4291
* Removes the unique index on users_apisessions for user_guid and site_guid
*/
diff --git a/engine/lib/upgrades/2013030600-1.8.13-update_user_location-8999eb8bf1bdd9a3.php b/engine/lib/upgrades/2013030600-1.8.13-update_user_location-8999eb8bf1bdd9a3.php
index b38eb5100..8eccf05e2 100644
--- a/engine/lib/upgrades/2013030600-1.8.13-update_user_location-8999eb8bf1bdd9a3.php
+++ b/engine/lib/upgrades/2013030600-1.8.13-update_user_location-8999eb8bf1bdd9a3.php
@@ -7,8 +7,6 @@
* This script turns that back into a string.
*/
-global $DB_QUERY_CACHE;
-
$ia = elgg_set_ignore_access(true);
$options = array(
'type' => 'user',
@@ -17,7 +15,7 @@ $options = array(
$batch = new ElggBatch('elgg_get_entities', $options);
foreach ($batch as $entity) {
- $DB_QUERY_CACHE = array();
+ _elgg_invalidate_query_cache();
if (is_array($entity->location)) {
$entity->location = implode(', ', $entity->location);
diff --git a/engine/lib/upgrades/2013051700-1.8.15-add_missing_group_index-52a63a3a3ffaced2.php b/engine/lib/upgrades/2013051700-1.8.15-add_missing_group_index-52a63a3a3ffaced2.php
new file mode 100644
index 000000000..ee99bdbc8
--- /dev/null
+++ b/engine/lib/upgrades/2013051700-1.8.15-add_missing_group_index-52a63a3a3ffaced2.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Elgg 1.8.15 upgrade 2013051700
+ * add_missing_group_index
+ *
+ * Some Elgg sites are missing the groups_entity full text index on name and
+ * description. This checks if it exists and adds it if it does not.
+ */
+
+$db_prefix = elgg_get_config('dbprefix');
+
+$full_text_index_exists = false;
+$results = get_data("SHOW INDEX FROM {$db_prefix}groups_entity");
+if ($results) {
+ foreach ($results as $result) {
+ if ($result->Index_type === 'FULLTEXT') {
+ $full_text_index_exists = true;
+ }
+ }
+}
+
+if ($full_text_index_exists == false) {
+ $query = "ALTER TABLE {$db_prefix}groups_entity
+ ADD FULLTEXT name_2 (name, description)";
+ if (!update_data($query)) {
+ elgg_log("Failed to add full text index to groups_entity table", 'ERROR');
+ }
+}
diff --git a/engine/lib/upgrades/2013052900-1.8.15-ipv6_in_syslog-f5c2cc0196e9e731.php b/engine/lib/upgrades/2013052900-1.8.15-ipv6_in_syslog-f5c2cc0196e9e731.php
new file mode 100644
index 000000000..d333a6cd2
--- /dev/null
+++ b/engine/lib/upgrades/2013052900-1.8.15-ipv6_in_syslog-f5c2cc0196e9e731.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * Elgg 1.8.15 upgrade 2013052900
+ * ipv6_in_syslog
+ *
+ * Upgrade the ip column in system_log to be able to store ipv6 addresses
+ */
+
+$db_prefix = elgg_get_config('dbprefix');
+$q = "ALTER TABLE {$db_prefix}system_log MODIFY COLUMN ip_address varchar(46) NOT NULL";
+
+update_data($q); \ No newline at end of file
diff --git a/engine/lib/user_settings.php b/engine/lib/user_settings.php
index 3466c25f9..0e36dc46d 100644
--- a/engine/lib/user_settings.php
+++ b/engine/lib/user_settings.php
@@ -308,7 +308,7 @@ function usersettings_page_handler($page) {
$user = get_user_by_username($page[1]);
elgg_set_page_owner_guid($user->guid);
} else {
- $user = elgg_get_logged_in_user_guid();
+ $user = elgg_get_logged_in_user_entity();
elgg_set_page_owner_guid($user->guid);
}
diff --git a/engine/lib/users.php b/engine/lib/users.php
index 4a585c07f..a8fb9121c 100644
--- a/engine/lib/users.php
+++ b/engine/lib/users.php
@@ -237,7 +237,7 @@ function make_user_admin($user_guid) {
}
$r = update_data("UPDATE {$CONFIG->dbprefix}users_entity set admin='yes' where guid=$user_guid");
- invalidate_cache_for_entity($user_guid);
+ _elgg_invalidate_cache_for_entity($user_guid);
return $r;
}
@@ -273,7 +273,7 @@ function remove_user_admin($user_guid) {
}
$r = update_data("UPDATE {$CONFIG->dbprefix}users_entity set admin='no' where guid=$user_guid");
- invalidate_cache_for_entity($user_guid);
+ _elgg_invalidate_cache_for_entity($user_guid);
return $r;
}
@@ -553,13 +553,18 @@ function get_user($guid) {
function get_user_by_username($username) {
global $CONFIG, $USERNAME_TO_GUID_MAP_CACHE;
+ // Fixes #6052. Username is frequently sniffed from the path info, which,
+ // unlike $_GET, is not URL decoded. If the username was not URL encoded,
+ // this is harmless.
+ $username = rawurldecode($username);
+
$username = sanitise_string($username);
$access = get_access_sql_suffix('e');
// Caching
if ((isset($USERNAME_TO_GUID_MAP_CACHE[$username]))
- && (retrieve_cached_entity($USERNAME_TO_GUID_MAP_CACHE[$username]))) {
- return retrieve_cached_entity($USERNAME_TO_GUID_MAP_CACHE[$username]);
+ && (_elgg_retrieve_cached_entity($USERNAME_TO_GUID_MAP_CACHE[$username]))) {
+ return _elgg_retrieve_cached_entity($USERNAME_TO_GUID_MAP_CACHE[$username]);
}
$query = "SELECT e.* from {$CONFIG->dbprefix}users_entity u
@@ -592,9 +597,9 @@ function get_user_by_code($code) {
// Caching
if ((isset($CODE_TO_GUID_MAP_CACHE[$code]))
- && (retrieve_cached_entity($CODE_TO_GUID_MAP_CACHE[$code]))) {
+ && (_elgg_retrieve_cached_entity($CODE_TO_GUID_MAP_CACHE[$code]))) {
- return retrieve_cached_entity($CODE_TO_GUID_MAP_CACHE[$code]);
+ return _elgg_retrieve_cached_entity($CODE_TO_GUID_MAP_CACHE[$code]);
}
$query = "SELECT e.* from {$CONFIG->dbprefix}users_entity u
@@ -705,18 +710,18 @@ function send_new_password_request($user_guid) {
* @return bool
*/
function force_user_password_reset($user_guid, $password) {
- global $CONFIG;
-
$user = get_entity($user_guid);
if ($user instanceof ElggUser) {
- $salt = generate_random_cleartext_password(); // Reset the salt
- $user->salt = $salt;
+ $ia = elgg_set_ignore_access();
- $hash = generate_user_password($user, $password);
+ $user->salt = generate_random_cleartext_password();
+ $hash = generate_user_password($user, $password);
+ $user->password = $hash;
+ $result = (bool)$user->save();
- $query = "UPDATE {$CONFIG->dbprefix}users_entity
- set password='$hash', salt='$salt' where guid=$user_guid";
- return update_data($query);
+ elgg_set_ignore_access($ia);
+
+ return $result;
}
return false;
@@ -1091,6 +1096,7 @@ function friends_page_handler($segments, $handler) {
* @access private
*/
function collections_page_handler($page_elements) {
+ gatekeeper();
elgg_set_context('friends');
$base = elgg_get_config('path');
if (isset($page_elements[0])) {
diff --git a/engine/lib/views.php b/engine/lib/views.php
index 7d8347863..fff3581cf 100644
--- a/engine/lib/views.php
+++ b/engine/lib/views.php
@@ -218,7 +218,7 @@ function elgg_register_ajax_view($view) {
/**
* Unregister a view for ajax calls
- *
+ *
* @param string $view The view name
* @return void
* @since 1.8.3
@@ -369,7 +369,7 @@ function elgg_view_exists($view, $viewtype = '', $recurse = true) {
* view, $view_name plugin hook.
*
* @warning Any variables in $_SESSION will override passed vars
- * upon name collision. See {@trac #2124}.
+ * upon name collision. See https://github.com/Elgg/Elgg/issues/2124
*
* @param string $view The name and location of the view to use
* @param array $vars Variables to pass to the view.
@@ -795,7 +795,7 @@ function elgg_view_menu($menu_name, array $vars = array()) {
* - bool 'full_view' Whether to show a full or condensed view.
*
* @tip This function can automatically appends annotations to entities if in full
- * view and a handler is registered for the entity:annotate. See {@trac 964} and
+ * view and a handler is registered for the entity:annotate. See https://github.com/Elgg/Elgg/issues/964 and
* {@link elgg_view_entity_annotations()}.
*
* @param ElggEntity $entity The entity to display
@@ -992,6 +992,11 @@ function elgg_view_annotation(ElggAnnotation $annotation, array $vars = array(),
function elgg_view_entity_list($entities, $vars = array(), $offset = 0, $limit = 10, $full_view = true,
$list_type_toggle = true, $pagination = true) {
+ if (!$vars["limit"] && !$vars["offset"]) {
+ // no need for pagination if listing is unlimited
+ $vars["pagination"] = false;
+ }
+
if (!is_int($offset)) {
$offset = (int)get_input('offset', 0);
}
@@ -1064,8 +1069,13 @@ function elgg_view_annotation_list($annotations, array $vars = array()) {
'full_view' => true,
'offset_key' => 'annoff',
);
-
+
$vars = array_merge($defaults, $vars);
+
+ if (!$vars["limit"] && !$vars["offset"]) {
+ // no need for pagination if listing is unlimited
+ $vars["pagination"] = false;
+ }
return elgg_view('page/components/list', $vars);
}
@@ -1107,7 +1117,7 @@ function elgg_view_entity_annotations(ElggEntity $entity, $full_view = true) {
* This is a shortcut for {@elgg_view page/elements/title}.
*
* @param string $title The page title
- * @param array $vars View variables (was submenu be displayed? (deprecated))
+ * @param array $vars View variables (was submenu be displayed? (deprecated))
*
* @return string The HTML (etc)
*/
@@ -1179,7 +1189,7 @@ function elgg_view_comments($entity, $add_comment = true, array $vars = array())
*
* @param string $image The icon and other information
* @param string $body Description content
- * @param array $vars Additional parameters for the view
+ * @param array $vars Additional parameters for the view
*
* @return string
* @since 1.8.0
@@ -1236,15 +1246,17 @@ function elgg_view_river_item($item, array $vars = array()) {
// subject is disabled or subject/object deleted
return '';
}
+
+ // @todo this needs to be cleaned up
// Don't hide objects in closed groups that a user can see.
- // see http://trac.elgg.org/ticket/4789
-// else {
-// // hide based on object's container
-// $visibility = ElggGroupItemVisibility::factory($object->container_guid);
-// if ($visibility->shouldHideItems) {
-// return '';
-// }
-// }
+ // see https://github.com/elgg/elgg/issues/4789
+ // else {
+ // // hide based on object's container
+ // $visibility = ElggGroupItemVisibility::factory($object->container_guid);
+ // if ($visibility->shouldHideItems) {
+ // return '';
+ // }
+ // }
$vars['item'] = $item;
@@ -1332,12 +1344,12 @@ function elgg_view_list_item($item, array $vars = array()) {
/**
* View one of the elgg sprite icons
- *
+ *
* Shorthand for <span class="elgg-icon elgg-icon-$name"></span>
- *
+ *
* @param string $name The specific icon to display
* @param string $class Additional class: float, float-alt, or custom class
- *
+ *
* @return string The html for displaying an icon
*/
function elgg_view_icon($name, $class = '') {
@@ -1636,7 +1648,7 @@ function elgg_views_boot() {
}
// set default icon sizes - can be overridden in settings.php or with plugin
- if (!$CONFIG->icon_sizes) {
+ if (!isset($CONFIG->icon_sizes)) {
$icon_sizes = array(
'topbar' => array('w' => 16, 'h' => 16, 'square' => TRUE, 'upscale' => TRUE),
'tiny' => array('w' => 25, 'h' => 25, 'square' => TRUE, 'upscale' => TRUE),
diff --git a/engine/lib/web_services.php b/engine/lib/web_services.php
index b6289184a..51cad6f39 100644
--- a/engine/lib/web_services.php
+++ b/engine/lib/web_services.php
@@ -1166,6 +1166,17 @@ function list_all_apis() {
* @access private
*/
function auth_gettoken($username, $password) {
+ // check if username is an email address
+ if (is_email_address($username)) {
+ $users = get_user_by_email($username);
+
+ // check if we have a unique user
+ if (is_array($users) && (count($users) == 1)) {
+ $username = $users[0]->username;
+ }
+ }
+
+ // validate username and password
if (true === elgg_authenticate($username, $password)) {
$token = create_user_token($username);
if ($token) {
@@ -1195,7 +1206,7 @@ $ERRORS = array();
*
* @return void
* @access private
- *
+ *
* @throws Exception
*/
function _php_api_error_handler($errno, $errmsg, $filename, $linenum, $vars) {
@@ -1267,14 +1278,14 @@ function service_handler($handler, $request) {
$request = explode('/', $request);
// after the handler, the first identifier is response format
- // ex) http://example.org/services/api/rest/xml/?method=test
+ // ex) http://example.org/services/api/rest/json/?method=test
$response_format = array_shift($request);
// Which view - xml, json, ...
if ($response_format && elgg_is_valid_view_type($response_format)) {
elgg_set_viewtype($response_format);
} else {
- // default to xml
- elgg_set_viewtype("xml");
+ // default to json
+ elgg_set_viewtype("json");
}
if (!isset($CONFIG->servicehandler) || empty($handler)) {
diff --git a/engine/schema/mysql.sql b/engine/schema/mysql.sql
index 6c6e9db89..4714b71bb 100644
--- a/engine/schema/mysql.sql
+++ b/engine/schema/mysql.sql
@@ -361,7 +361,7 @@ CREATE TABLE `prefix_system_log` (
`access_id` int(11) NOT NULL,
`enabled` enum('yes','no') NOT NULL DEFAULT 'yes',
`time_created` int(11) NOT NULL,
- `ip_address` varchar(15) NOT NULL,
+ `ip_address` varchar(46) NOT NULL,
PRIMARY KEY (`id`),
KEY `object_id` (`object_id`),
KEY `object_class` (`object_class`),
diff --git a/engine/tests/api/access_collections.php b/engine/tests/api/access_collections.php
index ebcd7d318..4acfae596 100644
--- a/engine/tests/api/access_collections.php
+++ b/engine/tests/api/access_collections.php
@@ -54,7 +54,6 @@ class ElggCoreAccessCollectionsTest extends ElggCoreUnitTest {
}
public function testCreateGetDeleteACL() {
- global $DB_QUERY_CACHE;
$acl_name = 'test access collection';
$acl_id = create_access_collection($acl_name);
@@ -67,8 +66,6 @@ class ElggCoreAccessCollectionsTest extends ElggCoreUnitTest {
$this->assertEqual($acl->id, $acl_id);
if ($acl) {
- $DB_QUERY_CACHE = array();
-
$this->assertEqual($acl->name, $acl_name);
$result = delete_access_collection($acl_id);
diff --git a/engine/tests/api/annotations.php b/engine/tests/api/annotations.php
index 947292970..c0b0687cc 100644
--- a/engine/tests/api/annotations.php
+++ b/engine/tests/api/annotations.php
@@ -65,6 +65,86 @@ class ElggCoreAnnotationAPITest extends ElggCoreUnitTest {
$annotations = elgg_get_annotations($options);
$this->assertTrue(empty($annotations));
+ // nothing to delete so null returned
+ $this->assertNull(elgg_delete_annotations($options));
+
+ $this->assertTrue($e->delete());
+ }
+
+ public function testElggDisableAnnotations() {
+ $e = new ElggObject();
+ $e->save();
+
+ for ($i=0; $i<30; $i++) {
+ $e->annotate('test_annotation', rand(0,10000));
+ }
+
+ $options = array(
+ 'guid' => $e->getGUID(),
+ 'limit' => 0
+ );
+
+ $this->assertTrue(elgg_disable_annotations($options));
+
+ $annotations = elgg_get_annotations($options);
+ $this->assertTrue(empty($annotations));
+
+ access_show_hidden_entities(true);
+ $annotations = elgg_get_annotations($options);
+ $this->assertIdentical(30, count($annotations));
+ access_show_hidden_entities(false);
+
+ $this->assertTrue($e->delete());
+ }
+
+ public function testElggEnableAnnotations() {
+ $e = new ElggObject();
+ $e->save();
+
+ for ($i=0; $i<30; $i++) {
+ $e->annotate('test_annotation', rand(0,10000));
+ }
+
+ $options = array(
+ 'guid' => $e->getGUID(),
+ 'limit' => 0
+ );
+
+ $this->assertTrue(elgg_disable_annotations($options));
+
+ // cannot see any annotations so returns null
+ $this->assertNull(elgg_enable_annotations($options));
+
+ access_show_hidden_entities(true);
+ $this->assertTrue(elgg_enable_annotations($options));
+ access_show_hidden_entities(false);
+
+ $annotations = elgg_get_annotations($options);
+ $this->assertIdentical(30, count($annotations));
+
+ $this->assertTrue($e->delete());
+ }
+
+ public function testElggAnnotationExists() {
+ $e = new ElggObject();
+ $e->save();
+ $guid = $e->getGUID();
+
+ $this->assertFalse(elgg_annotation_exists($guid, 'test_annotation'));
+
+ $e->annotate('test_annotation', rand(0, 10000));
+ $this->assertTrue(elgg_annotation_exists($guid, 'test_annotation'));
+ // this metastring should always exist but an annotation of this name should not
+ $this->assertFalse(elgg_annotation_exists($guid, 'email'));
+
+ $options = array(
+ 'guid' => $guid,
+ 'limit' => 0
+ );
+ $this->assertTrue(elgg_disable_annotations($options));
+ $this->assertTrue(elgg_annotation_exists($guid, 'test_annotation'));
+
$this->assertTrue($e->delete());
+ $this->assertFalse(elgg_annotation_exists($guid, 'test_annotation'));
}
}
diff --git a/engine/tests/api/entity_getter_functions.php b/engine/tests/api/entity_getter_functions.php
index 7bf8ef04a..fef9dc0c5 100644
--- a/engine/tests/api/entity_getter_functions.php
+++ b/engine/tests/api/entity_getter_functions.php
@@ -426,7 +426,7 @@ class ElggCoreEntityGetterFunctionsTest extends ElggCoreUnitTest {
$options = array(
'types' => $types,
- 'subtype' => $subtype
+ 'subtypes' => $subtype
);
$es = elgg_get_entities($options);
@@ -2755,7 +2755,7 @@ class ElggCoreEntityGetterFunctionsTest extends ElggCoreUnitTest {
'calculation' => 'count',
'count' => true,
);
- $count = (int)elgg_get_entities_from_annotation_calculation($options);
+ $count = elgg_get_entities_from_annotation_calculation($options);
$this->assertEqual(1, $count);
}
diff --git a/engine/tests/api/helpers.php b/engine/tests/api/helpers.php
index 62e4471e0..414fb4145 100644
--- a/engine/tests/api/helpers.php
+++ b/engine/tests/api/helpers.php
@@ -519,7 +519,7 @@ class ElggCoreHelpersTest extends ElggCoreUnitTest {
$this->assertIdentical($elements_sorted_string, $test_elements);
}
- // see http://trac.elgg.org/ticket/4288
+ // see https://github.com/elgg/elgg/issues/4288
public function testElggBatchIncOffset() {
// normal increment
$options = array(
@@ -578,6 +578,107 @@ class ElggCoreHelpersTest extends ElggCoreUnitTest {
$this->assertEqual(11, $j);
}
+ public function testElggBatchReadHandlesBrokenEntities() {
+ $num_test_entities = 8;
+ $guids = array();
+ for ($i = $num_test_entities; $i > 0; $i--) {
+ $entity = new ElggObject();
+ $entity->type = 'object';
+ $entity->subtype = 'test_5357_subtype';
+ $entity->access_id = ACCESS_PUBLIC;
+ $entity->save();
+ $guids[] = $entity->guid;
+ _elgg_invalidate_cache_for_entity($entity->guid);
+ }
+
+ // break entities such that the first fetch has one incomplete
+ // and the second and third fetches have only incompletes!
+ $db_prefix = elgg_get_config('dbprefix');
+ delete_data("
+ DELETE FROM {$db_prefix}objects_entity
+ WHERE guid IN ({$guids[1]}, {$guids[2]}, {$guids[3]}, {$guids[4]}, {$guids[5]})
+ ");
+
+ $options = array(
+ 'type' => 'object',
+ 'subtype' => 'test_5357_subtype',
+ 'order_by' => 'e.guid',
+ );
+
+ $entities_visited = array();
+ $batch = new ElggBatch('elgg_get_entities', $options, null, 2);
+ /* @var ElggEntity[] $batch */
+ foreach ($batch as $entity) {
+ $entities_visited[] = $entity->guid;
+ }
+
+ // The broken entities should not have been visited
+ $this->assertEqual($entities_visited, array($guids[0], $guids[6], $guids[7]));
+
+ // cleanup (including leftovers from previous tests)
+ $entity_rows = elgg_get_entities(array_merge($options, array(
+ 'callback' => '',
+ 'limit' => false,
+ )));
+ $guids = array();
+ foreach ($entity_rows as $row) {
+ $guids[] = $row->guid;
+ }
+ delete_data("DELETE FROM {$db_prefix}entities WHERE guid IN (" . implode(',', $guids) . ")");
+ delete_data("DELETE FROM {$db_prefix}objects_entity WHERE guid IN (" . implode(',', $guids) . ")");
+ }
+
+ public function testElggBatchDeleteHandlesBrokenEntities() {
+ $num_test_entities = 8;
+ $guids = array();
+ for ($i = $num_test_entities; $i > 0; $i--) {
+ $entity = new ElggObject();
+ $entity->type = 'object';
+ $entity->subtype = 'test_5357_subtype';
+ $entity->access_id = ACCESS_PUBLIC;
+ $entity->save();
+ $guids[] = $entity->guid;
+ _elgg_invalidate_cache_for_entity($entity->guid);
+ }
+
+ // break entities such that the first fetch has one incomplete
+ // and the second and third fetches have only incompletes!
+ $db_prefix = elgg_get_config('dbprefix');
+ delete_data("
+ DELETE FROM {$db_prefix}objects_entity
+ WHERE guid IN ({$guids[1]}, {$guids[2]}, {$guids[3]}, {$guids[4]}, {$guids[5]})
+ ");
+
+ $options = array(
+ 'type' => 'object',
+ 'subtype' => 'test_5357_subtype',
+ 'order_by' => 'e.guid',
+ );
+
+ $entities_visited = array();
+ $batch = new ElggBatch('elgg_get_entities', $options, null, 2, false);
+ /* @var ElggEntity[] $batch */
+ foreach ($batch as $entity) {
+ $entities_visited[] = $entity->guid;
+ $entity->delete();
+ }
+
+ // The broken entities should not have been visited
+ $this->assertEqual($entities_visited, array($guids[0], $guids[6], $guids[7]));
+
+ // cleanup (including leftovers from previous tests)
+ $entity_rows = elgg_get_entities(array_merge($options, array(
+ 'callback' => '',
+ 'limit' => false,
+ )));
+ $guids = array();
+ foreach ($entity_rows as $row) {
+ $guids[] = $row->guid;
+ }
+ delete_data("DELETE FROM {$db_prefix}entities WHERE guid IN (" . implode(',', $guids) . ")");
+ delete_data("DELETE FROM {$db_prefix}objects_entity WHERE guid IN (" . implode(',', $guids) . ")");
+ }
+
static function elgg_batch_callback_test($options, $reset = false) {
static $count = 1;
diff --git a/engine/tests/api/metadata.php b/engine/tests/api/metadata.php
index 825290d80..d23510c6a 100644
--- a/engine/tests/api/metadata.php
+++ b/engine/tests/api/metadata.php
@@ -123,9 +123,23 @@ class ElggCoreMetadataAPITest extends ElggCoreUnitTest {
$e->delete();
}
+ /**
+ * https://github.com/Elgg/Elgg/issues/4867
+ */
+ public function testElggGetEntityMetadataWhereSqlWithFalseValue() {
+ $pair = array('name' => 'test' , 'value' => false);
+ $result = elgg_get_entity_metadata_where_sql('e', 'metadata', null, null, $pair);
+ $where = preg_replace( '/\s+/', ' ', $result['wheres'][0]);
+ $this->assertTrue(strpos($where, "msn1.string = 'test' AND BINARY msv1.string = 0") > 0);
+
+ $result = elgg_get_entity_metadata_where_sql('e', 'metadata', array('test'), array(false));
+ $where = preg_replace( '/\s+/', ' ', $result['wheres'][0]);
+ $this->assertTrue(strpos($where, "msn.string IN ('test')) AND ( BINARY msv.string IN ('0')"));
+ }
+
// Make sure metadata with multiple values is correctly deleted when re-written
// by another user
- // http://trac.elgg.org/ticket/2776
+ // https://github.com/elgg/elgg/issues/2776
public function test_elgg_metadata_multiple_values() {
$u1 = new ElggUser();
$u1->username = rand();
diff --git a/engine/tests/api/metadata_cache.php b/engine/tests/api/metadata_cache.php
index 846116a7b..7fb328169 100644
--- a/engine/tests/api/metadata_cache.php
+++ b/engine/tests/api/metadata_cache.php
@@ -166,4 +166,11 @@ class ElggCoreMetadataCacheTest extends ElggCoreUnitTest {
$actual = $this->cache->filterMetadataHeavyEntities($guids, 6000);
$this->assertIdentical($actual, $expected);
}
+
+ public function testCreateMetadataInvalidates() {
+ $this->obj1->foo = 1;
+ create_metadata($this->guid1, 'foo', 2, '', elgg_get_logged_in_user_guid(), ACCESS_FRIENDS);
+
+ $this->assertEqual($this->obj1->foo, 2);
+ }
}
diff --git a/engine/tests/api/metastrings.php b/engine/tests/api/metastrings.php
index 0a8945084..5efdab972 100644
--- a/engine/tests/api/metastrings.php
+++ b/engine/tests/api/metastrings.php
@@ -55,8 +55,11 @@ class ElggCoreMetastringsTest extends ElggCoreUnitTest {
* Called after each test method.
*/
public function tearDown() {
- // do not allow SimpleTest to interpret Elgg notices as exceptions
- $this->swallowErrors();
+ access_show_hidden_entities(true);
+ elgg_delete_annotations(array(
+ 'guid' => $this->object->guid,
+ ));
+ access_show_hidden_entities(false);
}
/**
@@ -98,6 +101,31 @@ class ElggCoreMetastringsTest extends ElggCoreUnitTest {
}
}
+ public function testGetMetastringObjectFromIDWithDisabledAnnotation() {
+ $name = 'test_annotation_name' . rand();
+ $value = 'test_annotation_value' . rand();
+ $id = create_annotation($this->object->guid, $name, $value);
+ $annotation = elgg_get_annotation_from_id($id);
+ $this->assertTrue($annotation->disable());
+
+ $test = elgg_get_metastring_based_object_from_id($id, 'annotation');
+ $this->assertEqual(false, $test);
+ }
+
+ public function testGetMetastringBasedObjectWithDisabledAnnotation() {
+ $name = 'test_annotation_name' . rand();
+ $value = 'test_annotation_value' . rand();
+ $id = create_annotation($this->object->guid, $name, $value);
+ $annotation = elgg_get_annotation_from_id($id);
+ $this->assertTrue($annotation->disable());
+
+ $test = elgg_get_metastring_based_objects(array(
+ 'metastring_type' => 'annotations',
+ 'guid' => $this->object->guid,
+ ));
+ $this->assertEqual(array(), $test);
+ }
+
public function testEnableDisableByID() {
$db_prefix = elgg_get_config('dbprefix');
$annotations = $this->createAnnotations(1);
@@ -119,7 +147,6 @@ class ElggCoreMetastringsTest extends ElggCoreUnitTest {
// enable
$ashe = access_get_show_hidden_status();
access_show_hidden_entities(true);
- flush();
$this->assertTrue(elgg_set_metastring_based_object_enabled_by_id($id, 'yes', $type));
$test = get_data($q);
diff --git a/engine/tests/api/plugins.php b/engine/tests/api/plugins.php
index 114f3991b..d0f111c48 100644
--- a/engine/tests/api/plugins.php
+++ b/engine/tests/api/plugins.php
@@ -69,7 +69,7 @@ class ElggCorePluginsAPITest extends ElggCoreUnitTest {
'description' => 'A longer, more interesting description.',
'website' => 'http://www.elgg.org/',
'repository' => 'https://github.com/Elgg/Elgg',
- 'bugtracker' => 'http://trac.elgg.org',
+ 'bugtracker' => 'https://github.com/elgg/elgg/issues',
'donations' => 'http://elgg.org/supporter.php',
'copyright' => '(C) Elgg Foundation 2011',
'license' => 'GNU General Public License version 2',
@@ -174,7 +174,7 @@ class ElggCorePluginsAPITest extends ElggCoreUnitTest {
}
public function testElggPluginManifestGetBugtracker() {
- $this->assertEqual($this->manifest18->getBugTrackerURL(), 'http://trac.elgg.org');
+ $this->assertEqual($this->manifest18->getBugTrackerURL(), 'https://github.com/elgg/elgg/issues');
$this->assertEqual($this->manifest17->getBugTrackerURL(), '');
}
diff --git a/engine/tests/objects/entities.php b/engine/tests/objects/entities.php
index 248b85c9e..bac72079e 100644
--- a/engine/tests/objects/entities.php
+++ b/engine/tests/objects/entities.php
@@ -271,7 +271,7 @@ class ElggCoreEntityTest extends ElggCoreUnitTest {
$this->save_entity();
// test deleting incorrectly
- // @link http://trac.elgg.org/ticket/2273
+ // @link https://github.com/elgg/elgg/issues/2273
$this->assertNull($this->entity->deleteMetadata('impotent'));
$this->assertEqual($this->entity->important, 'indeed!');
diff --git a/engine/tests/objects/objects.php b/engine/tests/objects/objects.php
index 915594e0a..263ab2414 100644
--- a/engine/tests/objects/objects.php
+++ b/engine/tests/objects/objects.php
@@ -194,7 +194,7 @@ class ElggCoreObjectTest extends ElggCoreUnitTest {
$old = elgg_set_ignore_access(true);
}
- // see http://trac.elgg.org/ticket/1196
+ // see https://github.com/elgg/elgg/issues/1196
public function testElggEntityRecursiveDisableWhenLoggedOut() {
$e1 = new ElggObject();
$e1->access_id = ACCESS_PUBLIC;
diff --git a/engine/tests/objects/users.php b/engine/tests/objects/users.php
index a3573acb6..8a1033ac4 100644
--- a/engine/tests/objects/users.php
+++ b/engine/tests/objects/users.php
@@ -65,6 +65,9 @@ class ElggCoreUserTest extends ElggCoreUnitTest {
$attributes['code'] = NULL;
$attributes['banned'] = 'no';
$attributes['admin'] = 'no';
+ $attributes['prev_last_action'] = NULL;
+ $attributes['last_login'] = NULL;
+ $attributes['prev_last_login'] = NULL;
ksort($attributes);
$entity_attributes = $this->user->expose_attributes();
@@ -142,7 +145,7 @@ class ElggCoreUserTest extends ElggCoreUnitTest {
}
public function testElggUserNameCache() {
- // Trac #1305
+ // issue https://github.com/elgg/elgg/issues/1305
// very unlikely a user would have this username
$name = (string)time();
@@ -156,6 +159,22 @@ class ElggCoreUserTest extends ElggCoreUnitTest {
$this->assertFalse($user);
}
+ public function testGetUserByUsernameAcceptsUrlEncoded() {
+ $username = (string)time();
+ $this->user->username = $username;
+ $guid = $this->user->save();
+
+ // percent encode first letter
+ $first_letter = $username[0];
+ $first_letter = str_pad('%' . dechex(ord($first_letter)), 2, '0', STR_PAD_LEFT);
+ $username = $first_letter . substr($username, 1);
+
+ $user = get_user_by_username($username);
+ $this->assertTrue((bool) $user);
+ $this->assertEqual($guid, $user->guid);
+
+ $this->user->delete();
+ }
public function testElggUserMakeAdmin() {
global $CONFIG;
diff --git a/engine/tests/regression/trac_bugs.php b/engine/tests/regression/trac_bugs.php
index 691433a41..ef1348cf6 100644
--- a/engine/tests/regression/trac_bugs.php
+++ b/engine/tests/regression/trac_bugs.php
@@ -1,7 +1,7 @@
<?php
/**
- * Elgg Regression Tests -- Trac Bugfixes
- * Any bugfixes from Trac that require testing belong here.
+ * Elgg Regression Tests -- GitHub Bugfixes
+ * Any bugfixes from GitHub that require testing belong here.
*
* @package Elgg
* @subpackage Test
@@ -201,26 +201,28 @@ class ElggCoreRegressionBugsTest extends ElggCoreUnitTest {
}
/**
- * http://trac.elgg.org/ticket/3210 - Don't remove -s in friendly titles
- * http://trac.elgg.org/ticket/2276 - improve char encoding
+ * https://github.com/elgg/elgg/issues/3210 - Don't remove -s in friendly titles
+ * https://github.com/elgg/elgg/issues/2276 - improve char encoding
*/
public function test_friendly_title() {
$cases = array(
+ // acid test
+ "B&N > Amazon, OK? <bold> 'hey!' $34"
+ => "bn-amazon-ok-bold-hey-34",
+
// hyphen, underscore and ASCII whitespace replaced by separator,
// other non-alphanumeric ASCII removed
- "a-a_a a\na\ra\ta\va!a\"a#a\$a%a&a'a(a)a*a+a,a.a/a:a;a<a=a>a?a@a[a\\a]a^a`a{a|a}a~a"
- => "a-a-a-a-a-a-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-
+ "a-a_a a\na\ra\ta\va!a\"a#a\$a%aa'a(a)a*a+a,a.a/a:a;a=a?a@a[a\\a]a^a`a{a|a}a~a"
+ => "a-a-a-a-a-a-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+
// separators trimmed
- "-_ hello _-" => "hello",
+ "-_ hello _-"
+ => "hello",
// accents removed, lower case, other multibyte chars are URL encoded
"I\xC3\xB1t\xC3\xABrn\xC3\xA2ti\xC3\xB4n\xC3\xA0liz\xC3\xA6ti\xC3\xB8n, AND \xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E"
// Iñtërnâtiônàlizætiøn, AND 日本語
=> 'internationalizaetion-and-%E6%97%A5%E6%9C%AC%E8%AA%9E',
-
- // some HTML entity replacements
- "Me &amp; You" => 'me-and-you',
);
// where available, string is converted to NFC before transliteration
@@ -234,4 +236,141 @@ class ElggCoreRegressionBugsTest extends ElggCoreUnitTest {
$this->assertIdentical($expected, $friendly_title);
}
}
+
+ /**
+ * Test #5369 -- parse_urls()
+ * https://github.com/Elgg/Elgg/issues/5369
+ */
+ public function test_parse_urls() {
+
+ $cases = array(
+ 'no.link.here' =>
+ 'no.link.here',
+ 'simple link http://example.org test' =>
+ 'simple link <a href="http://example.org" rel="nofollow">http:/<wbr />/<wbr />example.org</a> test',
+ 'non-ascii http://ñew.org/ test' =>
+ 'non-ascii <a href="http://ñew.org/" rel="nofollow">http:/<wbr />/<wbr />ñew.org/<wbr /></a> test',
+
+ // section 2.1
+ 'percent encoded http://example.org/a%20b test' =>
+ 'percent encoded <a href="http://example.org/a%20b" rel="nofollow">http:/<wbr />/<wbr />example.org/<wbr />a%20b</a> test',
+ // section 2.2: skipping single quote and parenthese
+ 'reserved characters http://example.org/:/?#[]@!$&*+,;= test' =>
+ 'reserved characters <a href="http://example.org/:/?#[]@!$&*+,;=" rel="nofollow">http:/<wbr />/<wbr />example.org/<wbr />:/<wbr />?#[]@!$&*+,;=</a> test',
+ // section 2.3
+ 'unreserved characters http://example.org/a1-._~ test' =>
+ 'unreserved characters <a href="http://example.org/a1-._~" rel="nofollow">http:/<wbr />/<wbr />example.org/<wbr />a1-._~</a> test',
+
+ 'parameters http://example.org/?val[]=1&val[]=2 test' =>
+ 'parameters <a href="http://example.org/?val[]=1&val[]=2" rel="nofollow">http:/<wbr />/<wbr />example.org/<wbr />?val[]=1&val[]=2</a> test',
+ 'port http://example.org:80/ test' =>
+ 'port <a href="http://example.org:80/" rel="nofollow">http:/<wbr />/<wbr />example.org:80/<wbr /></a> test',
+
+ 'parentheses (http://www.google.com) test' =>
+ 'parentheses (<a href="http://www.google.com" rel="nofollow">http:/<wbr />/<wbr />www.google.com</a>) test',
+ 'comma http://elgg.org, test' =>
+ 'comma <a href="http://elgg.org" rel="nofollow">http:/<wbr />/<wbr />elgg.org</a>, test',
+ 'period http://elgg.org. test' =>
+ 'period <a href="http://elgg.org" rel="nofollow">http:/<wbr />/<wbr />elgg.org</a>. test',
+ 'exclamation http://elgg.org! test' =>
+ 'exclamation <a href="http://elgg.org" rel="nofollow">http:/<wbr />/<wbr />elgg.org</a>! test',
+
+ 'already anchor <a href="http://twitter.com/">twitter</a> test' =>
+ 'already anchor <a href="http://twitter.com/">twitter</a> test',
+
+ 'ssl https://example.org/ test' =>
+ 'ssl <a href="https://example.org/" rel="nofollow">https:/<wbr />/<wbr />example.org/<wbr /></a> test',
+ 'ftp ftp://example.org/ test' =>
+ 'ftp <a href="ftp://example.org/" rel="nofollow">ftp:/<wbr />/<wbr />example.org/<wbr /></a> test',
+
+ 'web archive anchor <a href="http://web.archive.org/web/20000229040250/http://www.google.com/">google</a>' =>
+ 'web archive anchor <a href="http://web.archive.org/web/20000229040250/http://www.google.com/">google</a>',
+
+ 'single quotes already anchor <a href=\'http://www.yahoo.com\'>yahoo</a>' =>
+ 'single quotes already anchor <a href=\'http://www.yahoo.com\'>yahoo</a>',
+
+ 'unquoted already anchor <a href=http://www.yahoo.com>yahoo</a>' =>
+ 'unquoted already anchor <a href=http://www.yahoo.com>yahoo</a>',
+
+ 'parens in uri http://thedailywtf.com/Articles/A-(Long-Overdue)-BuildMaster-Introduction.aspx' =>
+ 'parens in uri <a href="http://thedailywtf.com/Articles/A-(Long-Overdue)-BuildMaster-Introduction.aspx" rel="nofollow">http:/<wbr />/<wbr />thedailywtf.com/<wbr />Articles/<wbr />A-(Long-Overdue)-BuildMaster-Introduction.aspx</a>'
+ );
+ foreach ($cases as $input => $output) {
+ $this->assertEqual($output, parse_urls($input));
+ }
+ }
+
+ /**
+ * Ensure additional select columns do not end up in entity attributes.
+ *
+ * https://github.com/Elgg/Elgg/issues/5538
+ */
+ public function test_extra_columns_dont_appear_in_attributes() {
+ global $ENTITY_CACHE;
+
+ // may not have groups in DB - let's create one
+ $group = new ElggGroup();
+ $group->name = 'test_group';
+ $group->access_id = ACCESS_PUBLIC;
+ $this->assertTrue($group->save() !== false);
+
+ // entity cache interferes with our test
+ $ENTITY_CACHE = array();
+
+ foreach (array('site', 'user', 'group', 'object') as $type) {
+ $entities = elgg_get_entities(array(
+ 'type' => $type,
+ 'selects' => array('1 as _nonexistent_test_column'),
+ 'limit' => 1,
+ ));
+ if (!$this->assertTrue($entities, "Query for '$type' did not return an entity.")) {
+ continue;
+ }
+ $entity = $entities[0];
+ $this->assertNull($entity->_nonexistent_test_column, "Additional select columns are leaking to attributes for '$type'");
+ }
+
+ $group->delete();
+ }
+
+ /**
+ * Ensure that ElggBatch doesn't go into infinite loop when disabling annotations recursively when show hidden is enabled.
+ *
+ * https://github.com/Elgg/Elgg/issues/5952
+ */
+ public function test_disabling_annotations_infinite_loop() {
+
+ //let's have some entity
+ $group = new ElggGroup();
+ $group->name = 'test_group';
+ $group->access_id = ACCESS_PUBLIC;
+ $this->assertTrue($group->save() !== false);
+
+ $total = 51;
+ //add some annotations
+ for ($cnt = 0; $cnt < $total; $cnt++) {
+ $group->annotate('test_annotation', 'value_' . $total);
+ }
+
+ //disable them
+ $show_hidden = access_get_show_hidden_status();
+ access_show_hidden_entities(true);
+ $options = array(
+ 'guid' => $group->guid,
+ 'limit' => $total, //using strict limit to avoid real infinite loop and just see ElggBatch limiting on it before finishing the work
+ );
+ elgg_disable_annotations($options);
+ access_show_hidden_entities($show_hidden);
+
+ //confirm all being disabled
+ $annotations = $group->getAnnotations(array(
+ 'limit' => $total,
+ ));
+ foreach ($annotations as $annotation) {
+ $this->assertTrue($annotation->enabled == 'no');
+ }
+
+ //delete group and annotations
+ $group->delete();
+ }
}
diff --git a/engine/tests/test_files/plugin_18/manifest.xml b/engine/tests/test_files/plugin_18/manifest.xml
index 5d788616a..c8b407511 100644
--- a/engine/tests/test_files/plugin_18/manifest.xml
+++ b/engine/tests/test_files/plugin_18/manifest.xml
@@ -7,7 +7,7 @@
<description>A longer, more interesting description.</description>
<website>http://www.elgg.org/</website>
<repository>https://github.com/Elgg/Elgg</repository>
- <bugtracker>http://trac.elgg.org</bugtracker>
+ <bugtracker>https://github.com/elgg/elgg/issues</bugtracker>
<donations>http://elgg.org/supporter.php</donations>
<copyright>(C) Elgg Foundation 2011</copyright>
<license>GNU General Public License version 2</license>
diff --git a/htaccess_dist b/htaccess_dist
index 898fa22fb..44d129475 100644
--- a/htaccess_dist
+++ b/htaccess_dist
@@ -112,6 +112,14 @@ RewriteEngine on
#
#RewriteBase /
+
+# If your users receive the message "Sorry, logging in from a different domain is not permitted"
+# you must make sure your login form is served from the same hostname as your site pages.
+# See http://docs.elgg.org/wiki/Login_token_mismatch_error for more info.
+#
+# If you must add RewriteRules to change hostname, add them directly below (above all the others)
+
+
# In for backwards compatibility
RewriteRule ^pg\/([A-Za-z0-9\_\-]+)$ engine/handlers/page_handler.php?handler=$1&%{QUERY_STRING} [L]
RewriteRule ^pg\/([A-Za-z0-9\_\-]+)\/(.*)$ engine/handlers/page_handler.php?handler=$1&page=$2&%{QUERY_STRING} [L]
diff --git a/install/ElggInstaller.php b/install/ElggInstaller.php
index 93716f7cd..78cdde90f 100644
--- a/install/ElggInstaller.php
+++ b/install/ElggInstaller.php
@@ -1414,7 +1414,7 @@ class ElggInstaller {
$submissionVars['wwwroot'] = sanitise_filepath($submissionVars['wwwroot']);
$site = new ElggSite();
- $site->name = $submissionVars['sitename'];
+ $site->name = strip_tags($submissionVars['sitename']);
$site->url = $submissionVars['wwwroot'];
$site->access_id = ACCESS_PUBLIC;
$site->email = $submissionVars['siteemail'];
diff --git a/install/cli/sample_installer.php b/install/cli/sample_installer.php
index 0bae0cd23..a51f9aae4 100644
--- a/install/cli/sample_installer.php
+++ b/install/cli/sample_installer.php
@@ -1,28 +1,12 @@
<?php
+
/**
* Sample cli installer script
*/
+// change to true to run this script. Change back to false when done.
$enabled = false;
-// Do not edit below this line. //////////////////////////////
-
-
-if (!$enabled) {
- echo "To enable this script, change \$enabled to true.\n";
- echo "You *must* disable this script after a successful installation.\n";
- exit;
-}
-
-if (PHP_SAPI !== 'cli') {
- echo "You must use the command line to run this script.";
- exit;
-}
-
-require_once(dirname(dirname(__FILE__)) . "/ElggInstaller.php");
-
-$installer = new ElggInstaller();
-
// none of the following may be empty
$params = array(
// database parameters
@@ -43,11 +27,29 @@ $params = array(
'password' => '',
);
+
+// Do not edit below this line. //////////////////////////////
+
+
+if (!$enabled) {
+ echo "To enable this script, change \$enabled to true.\n";
+ echo "You *must* disable this script after a successful installation.\n";
+ exit;
+}
+
+if (PHP_SAPI !== 'cli') {
+ echo "You must use the command line to run this script.";
+ exit;
+}
+
+require_once(dirname(dirname(__FILE__)) . "/ElggInstaller.php");
+
+$installer = new ElggInstaller();
+
// install and create the .htaccess file
$installer->batchInstall($params, TRUE);
// at this point installation has completed (otherwise an exception halted execution).
-
// try to rewrite the script to disable it.
if (is_writable(__FILE__)) {
$code = file_get_contents(__FILE__);
diff --git a/js/lib/elgglib.js b/js/lib/elgglib.js
index af2c94000..a8e187f1d 100644
--- a/js/lib/elgglib.js
+++ b/js/lib/elgglib.js
@@ -474,8 +474,8 @@ elgg.parse_str = function(string) {
re = /([^&=]+)=?([^&]*)/g;
while (result = re.exec(string)) {
- key = decodeURIComponent(result[1])
- value = decodeURIComponent(result[2])
+ key = decodeURIComponent(result[1].replace(/\+/g, ' '));
+ value = decodeURIComponent(result[2].replace(/\+/g, ' '));
params[key] = value;
}
diff --git a/js/lib/languages.js b/js/lib/languages.js
index 44ea56d2b..d218cbc4f 100644
--- a/js/lib/languages.js
+++ b/js/lib/languages.js
@@ -30,6 +30,9 @@ elgg.reload_all_translations = function(language) {
var url, options;
url = 'ajax/view/js/languages';
options = {data: {language: lang}};
+ if (elgg.config.simplecache_enabled) {
+ options.data.lc = elgg.config.lastcache;
+ }
options['success'] = function(json) {
elgg.add_translation(lang, json);
diff --git a/js/lib/session.js b/js/lib/session.js
index fa3d60aa9..a8d52733c 100644
--- a/js/lib/session.js
+++ b/js/lib/session.js
@@ -14,9 +14,9 @@ elgg.provide('elgg.session');
* {string} options[domain]
* {boolean} options[secure]
*
- * @return {string} The value of the cookie, if only name is specified
+ * @return {string|undefined} The value of the cookie, if only name is specified. Undefined if no value set
*/
-elgg.session.cookie = function (name, value, options) {
+elgg.session.cookie = function(name, value, options) {
var cookies = [], cookie = [], i = 0, date, valid = true;
//elgg.session.cookie()
@@ -47,21 +47,19 @@ elgg.session.cookie = function (name, value, options) {
}
cookies.push(name + '=' + value);
-
- if (elgg.isNumber(options.expires)) {
- if (elgg.isNumber(options.expires)) {
- date = new Date();
- date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
- } else if (options.expires.toUTCString) {
- date = options.expires;
- } else {
- valid = false;
- }
-
- if (valid) {
- cookies.push('expires=' + date.toUTCString());
- }
- }
+
+ if (options.expires) {
+ if (elgg.isNumber(options.expires)) {
+ date = new Date();
+ date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
+ } else if (options.expires.toUTCString) {
+ date = options.expires;
+ }
+
+ if (date) {
+ cookies.push('expires=' + date.toUTCString());
+ }
+ }
// CAUTION: Needed to parenthesize options.path and options.domain
// in the following expressions, otherwise they evaluate to undefined
diff --git a/js/lib/ui.river.js b/js/lib/ui.river.js
index a56a664a4..c103fabb3 100644
--- a/js/lib/ui.river.js
+++ b/js/lib/ui.river.js
@@ -1,14 +1,14 @@
-elgg.provide('elgg.ui.river');
-
-elgg.ui.river.init = function() {
- $('#elgg-river-selector').change(function() {
- var url = window.location.href;
- if (window.location.search.length) {
- url = url.substring(0, url.indexOf('?'));
- }
- url += '?' + $(this).val();
- elgg.forward(url);
- });
-};
-
+elgg.provide('elgg.ui.river');
+
+elgg.ui.river.init = function() {
+ $('#elgg-river-selector').change(function() {
+ var url = window.location.href;
+ if (window.location.search.length) {
+ url = url.substring(0, url.indexOf('?'));
+ }
+ url += '?' + $(this).val();
+ elgg.forward(url);
+ });
+};
+
elgg.register_hook_handler('init', 'system', elgg.ui.river.init); \ No newline at end of file
diff --git a/js/lib/ui.userpicker.js b/js/lib/ui.userpicker.js
index 7298da114..669b84cdb 100644
--- a/js/lib/ui.userpicker.js
+++ b/js/lib/ui.userpicker.js
@@ -107,11 +107,11 @@ elgg.userpicker.viewUser = function(info) {
* @return Object
*/
elgg.userpicker.getSearchParams = function(obj) {
- if (obj.element.siblings('[name=match_on]').attr('checked')) {
+ if (obj.element.parent('.elgg-user-picker').find('input[name=match_on]').attr('checked')) {
return {'match_on[]': 'friends', 'term' : obj.term};
} else {
return {'match_on[]': 'users', 'term' : obj.term};
}
};
-elgg.register_hook_handler('init', 'system', elgg.userpicker.init); \ No newline at end of file
+elgg.register_hook_handler('init', 'system', elgg.userpicker.init);
diff --git a/js/tests/ElggLibTest.js b/js/tests/ElggLibTest.js
index 2a676e22a..bd39e7fb3 100644
--- a/js/tests/ElggLibTest.js
+++ b/js/tests/ElggLibTest.js
@@ -78,6 +78,7 @@ ElggLibTest.prototype.testNormalizeUrl = function() {
['https://example.com', 'https://example.com'],
['http://example-time.com', 'http://example-time.com'],
['//example.com', '//example.com'],
+ ['mod/my_plugin/graphics/image.jpg', elgg.config.wwwroot + 'mod/my_plugin/graphics/image.jpg'],
['ftp://example.com/file', 'ftp://example.com/file'],
['mailto:brett@elgg.org', 'mailto:brett@elgg.org'],
@@ -127,3 +128,13 @@ ElggLibTest.prototype.testParseUrl = function() {
});
};
+ElggLibTest.prototype.testParseStr = function() {
+
+ [
+ ["A+%2B+B=A+%2B+B", {"A + B": "A + B"}]
+
+ ].forEach(function(args) {
+ assertEquals(args[1], elgg.parse_str(args[0]));
+ });
+};
+
diff --git a/js/tests/README b/js/tests/README
index 4f86b27c6..f43c0c89d 100644
--- a/js/tests/README
+++ b/js/tests/README
@@ -12,9 +12,10 @@ based debuggers. Visit its wiki at the Google Code site for more information.
Sample Usage
============
1. Put jar file in the base directory of Elgg
- 2. Run the server: java -jar JsTestDriver-1.3.3d.jar --port 4224
+ 2. Run the server: java -jar JsTestDriver-1.3.5.jar --port 4224
3. Point a web browser at http://localhost:4224
- 4. Run the tests: java -jar JsTestDriver-1.3.3d.jar --config js/tests/jsTestDriver.conf --basePath . --tests all
+ 4. Click "Capture this browser"
+ 5. Run the tests: java -jar JsTestDriver-1.3.5.jar --config js/tests/jsTestDriver.conf --basePath . --tests all
Configuration Hints
diff --git a/languages/en.php b/languages/en.php
index fe450b8a2..ad4831db7 100644
--- a/languages/en.php
+++ b/languages/en.php
@@ -105,6 +105,8 @@ $english = array(
'ElggPlugin:Dependencies:Priority:Before' => 'Before %s',
'ElggPlugin:Dependencies:Priority:Uninstalled' => '%s is not installed',
'ElggPlugin:Dependencies:Suggests:Unsatisfied' => 'Missing',
+
+ 'ElggPlugin:Dependencies:ActiveDependent' => 'There are other plugins that list %s as a dependency. You must disable the following plugins before disabling this one: %s',
'ElggPlugin:InvalidAndDeactivated' => '%s is an invalid plugin and has been deactivated.',
@@ -175,7 +177,7 @@ $english = array(
'ConfigurationException:NoSiteID' => "No site ID has been specified.",
'SecurityException:APIAccessDenied' => "Sorry, API access has been disabled by the administrator.",
'SecurityException:NoAuthMethods' => "No authentication methods were found that could authenticate this API request.",
- 'SecurityException:ForwardFailedToRedirect' => 'Redirect could not be issued due to headers already being sent. Halting execution for security. Search http://docs.elgg.org/ for more information.',
+ 'SecurityException:ForwardFailedToRedirect' => 'Redirect could not be issued due to headers already being sent. Halting execution for security. Output started in file %s at line %d. Search http://docs.elgg.org/ for more information.',
'InvalidParameterException:APIMethodOrFunctionNotSet' => "Method or function not set in call in expose_method()",
'InvalidParameterException:APIParametersArrayStructure' => "Parameters array structure is incorrect for call to expose method '%s'",
'InvalidParameterException:UnrecognisedHttpMethod' => "Unrecognised http method %s for api method '%s'",
@@ -359,6 +361,7 @@ $english = array(
'friendspicker:chararray' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'avatar' => 'Avatar',
+ 'avatar:noaccess' => "You're not allowed to edit this user's avatar",
'avatar:create' => 'Create your avatar',
'avatar:edit' => 'Edit avatar',
'avatar:preview' => 'Preview',
@@ -902,6 +905,7 @@ $english = array(
'total' => 'Total',
'learnmore' => "Click here to learn more.",
+ 'unknown_error' => 'Unknown error',
'content' => "content",
'content:latest' => 'Latest activity',
@@ -1193,6 +1197,7 @@ You cannot reply to this email.",
'actiongatekeeper:timeerror' => 'The page you were using has expired. Please refresh and try again.',
'actiongatekeeper:pluginprevents' => 'A extension has prevented this form from being submitted.',
'actiongatekeeper:uploadexceeded' => 'The size of file(s) uploaded exceeded the limit set by your site administrator',
+ 'actiongatekeeper:crosssitelogin' => "Sorry, logging in from a different domain is not permitted. Please try again.",
/**
diff --git a/mod/blog/actions/blog/save.php b/mod/blog/actions/blog/save.php
index 9256610cc..82a9e6c51 100644
--- a/mod/blog/actions/blog/save.php
+++ b/mod/blog/actions/blog/save.php
@@ -79,11 +79,7 @@ foreach ($values as $name => $default) {
switch ($name) {
case 'tags':
- if ($value) {
- $values[$name] = string_to_tag_array($value);
- } else {
- unset ($values[$name]);
- }
+ $values[$name] = string_to_tag_array($value);
break;
case 'excerpt':
@@ -125,10 +121,7 @@ if ($values['status'] == 'draft') {
// assign values to the entity, stopping on error.
if (!$error) {
foreach ($values as $name => $value) {
- if (FALSE === ($blog->$name = $value)) {
- $error = elgg_echo('blog:error:cannot_save' . "$name=$value");
- break;
- }
+ $blog->$name = $value;
}
}
diff --git a/mod/blog/start.php b/mod/blog/start.php
index 25cd81935..e724b91c2 100644
--- a/mod/blog/start.php
+++ b/mod/blog/start.php
@@ -113,14 +113,23 @@ function blog_page_handler($page) {
switch ($page_type) {
case 'owner':
$user = get_user_by_username($page[1]);
+ if (!$user) {
+ forward('', '404');
+ }
$params = blog_get_page_content_list($user->guid);
break;
case 'friends':
$user = get_user_by_username($page[1]);
+ if (!$user) {
+ forward('', '404');
+ }
$params = blog_get_page_content_friends($user->guid);
break;
case 'archive':
$user = get_user_by_username($page[1]);
+ if (!$user) {
+ forward('', '404');
+ }
$params = blog_get_page_content_archive($user->guid, $page[2], $page[3]);
break;
case 'view':
@@ -139,7 +148,11 @@ function blog_page_handler($page) {
$params = blog_get_page_content_edit($page_type, $page[1], $page[2]);
break;
case 'group':
- if ($page[2] == 'all') {
+ $group = get_entity($page[1]);
+ if (!elgg_instanceof($group, 'group')) {
+ forward('', '404');
+ }
+ if (!isset($page[2]) || $page[2] == 'all') {
$params = blog_get_page_content_list($page[1]);
} else {
$params = blog_get_page_content_archive($page[1], $page[3], $page[4]);
diff --git a/mod/blog/views/default/blog/sidebar/archives.php b/mod/blog/views/default/blog/sidebar/archives.php
index 3d8f28ca4..5098e6e3e 100644
--- a/mod/blog/views/default/blog/sidebar/archives.php
+++ b/mod/blog/views/default/blog/sidebar/archives.php
@@ -14,7 +14,7 @@ if (elgg_instanceof($page_owner, 'user')) {
// This is a limitation of the URL schema.
if ($page_owner && $vars['page'] != 'friends') {
- $dates = get_entity_dates('object', 'blog', $page_owner->getGUID());
+ $dates = array_reverse(get_entity_dates('object', 'blog', $page_owner->getGUID()));
if ($dates) {
$title = elgg_echo('blog:archives');
diff --git a/mod/blog/views/default/forms/blog/save.php b/mod/blog/views/default/forms/blog/save.php
index 36fa2e0e8..f825acca1 100644
--- a/mod/blog/views/default/forms/blog/save.php
+++ b/mod/blog/views/default/forms/blog/save.php
@@ -10,7 +10,7 @@ $vars['entity'] = $blog;
$draft_warning = $vars['draft_warning'];
if ($draft_warning) {
- $draft_warning = '<span class="message warning">' . $draft_warning . '</span>';
+ $draft_warning = '<span class="mbm elgg-text-help">' . $draft_warning . '</span>';
}
$action_buttons = '';
diff --git a/mod/blog/views/default/river/object/blog/create.php b/mod/blog/views/default/river/object/blog/create.php
index a054c1061..b808f1bdc 100644
--- a/mod/blog/views/default/river/object/blog/create.php
+++ b/mod/blog/views/default/river/object/blog/create.php
@@ -4,10 +4,12 @@
*/
$object = $vars['item']->getObjectEntity();
-$excerpt = strip_tags($object->excerpt);
+
+$excerpt = $object->excerpt ? $object->excerpt : $object->description;
+$excerpt = strip_tags($excerpt);
$excerpt = elgg_get_excerpt($excerpt);
echo elgg_view('river/elements/layout', array(
'item' => $vars['item'],
'message' => $excerpt,
-)); \ No newline at end of file
+));
diff --git a/mod/bookmarks/languages/en.php b/mod/bookmarks/languages/en.php
index d4980280d..970b39415 100644
--- a/mod/bookmarks/languages/en.php
+++ b/mod/bookmarks/languages/en.php
@@ -9,7 +9,7 @@ $english = array(
* Menu items and titles
*/
'bookmarks' => "Bookmarks",
- 'bookmarks:add' => "Add bookmark",
+ 'bookmarks:add' => "Add a bookmark",
'bookmarks:edit' => "Edit bookmark",
'bookmarks:owner' => "%s's bookmarks",
'bookmarks:friends' => "Friends' bookmarks",
diff --git a/mod/bookmarks/pages/bookmarks/all.php b/mod/bookmarks/pages/bookmarks/all.php
index bdb8fc793..5c6011ad9 100644
--- a/mod/bookmarks/pages/bookmarks/all.php
+++ b/mod/bookmarks/pages/bookmarks/all.php
@@ -13,9 +13,8 @@ elgg_register_title_button();
$content = elgg_list_entities(array(
'type' => 'object',
'subtype' => 'bookmarks',
- 'limit' => 10,
'full_view' => false,
- 'view_toggle_type' => false
+ 'view_toggle_type' => false,
));
if (!$content) {
diff --git a/mod/bookmarks/pages/bookmarks/friends.php b/mod/bookmarks/pages/bookmarks/friends.php
index 15b1da098..173996346 100644
--- a/mod/bookmarks/pages/bookmarks/friends.php
+++ b/mod/bookmarks/pages/bookmarks/friends.php
@@ -7,7 +7,7 @@
$page_owner = elgg_get_page_owner_entity();
if (!$page_owner) {
- forward('bookmarks/all');
+ forward('', '404');
}
elgg_push_breadcrumb($page_owner->name, "bookmarks/owner/$page_owner->username");
diff --git a/mod/bookmarks/pages/bookmarks/owner.php b/mod/bookmarks/pages/bookmarks/owner.php
index a024ff352..b7b907916 100644
--- a/mod/bookmarks/pages/bookmarks/owner.php
+++ b/mod/bookmarks/pages/bookmarks/owner.php
@@ -7,7 +7,7 @@
$page_owner = elgg_get_page_owner_entity();
if (!$page_owner) {
- forward('bookmarks/all');
+ forward('', '404');
}
elgg_push_breadcrumb($page_owner->name);
@@ -18,7 +18,6 @@ $content .= elgg_list_entities(array(
'type' => 'object',
'subtype' => 'bookmarks',
'container_guid' => $page_owner->guid,
- 'limit' => 10,
'full_view' => false,
'view_toggle_type' => false
));
diff --git a/mod/bookmarks/start.php b/mod/bookmarks/start.php
index 3846f5165..caea43587 100644
--- a/mod/bookmarks/start.php
+++ b/mod/bookmarks/start.php
@@ -56,6 +56,9 @@ function bookmarks_init() {
// Listen to notification events and supply a more useful message
elgg_register_plugin_hook_handler('notify:entity:message', 'object', 'bookmarks_notify_message');
+ // Register bookmarks view for ecml parsing
+ elgg_register_plugin_hook_handler('get_views', 'ecml', 'bookmarks_ecml_views_hook');
+
// Register a URL handler for bookmarks
elgg_register_entity_url_handler('object', 'bookmarks', 'bookmark_url');
@@ -282,8 +285,11 @@ function bookmarks_page_menu($hook, $type, $return, $params) {
if (!$page_owner) {
$page_owner = elgg_get_logged_in_user_entity();
}
-
+
if ($page_owner instanceof ElggGroup) {
+ if (!$page_owner->isMember()) {
+ return $return;
+ }
$title = elgg_echo('bookmarks:bookmarklet:group');
} else {
$title = elgg_echo('bookmarks:bookmarklet');
@@ -295,3 +301,16 @@ function bookmarks_page_menu($hook, $type, $return, $params) {
return $return;
}
+
+/**
+ * Return bookmarks views to parse for ecml
+ *
+ * @param string $hook
+ * @param string $type
+ * @param array $return
+ * @param array $params
+ */
+function bookmarks_ecml_views_hook($hook, $type, $return, $params) {
+ $return['object/bookmarks'] = elgg_echo('item:object:bookmarks');
+ return $return;
+}
diff --git a/mod/developers/languages/en.php b/mod/developers/languages/en.php
index 856efe008..266b5406e 100644
--- a/mod/developers/languages/en.php
+++ b/mod/developers/languages/en.php
@@ -28,7 +28,8 @@ $english = array(
'developers:label:show_strings' => "Show raw translation strings",
'developers:help:show_strings' => "This displays the translation strings used by elgg_echo().",
'developers:label:wrap_views' => "Wrap views",
- 'developers:help:wrap_views' => "This wraps almost every view with HTML comments. Useful for finding the view creating particular HTML.",
+ 'developers:help:wrap_views' => "This wraps almost every view with HTML comments. Useful for finding the view creating particular HTML.
+ This can break non-HTML views in the default viewtype. See developers_wrap_views() for details.",
'developers:label:log_events' => "Log events and plugin hooks",
'developers:help:log_events' => "Write events and plugin hooks to the log. Warning: there are many of these per page.",
diff --git a/mod/developers/manifest.xml b/mod/developers/manifest.xml
index e31998872..23e726e2b 100644
--- a/mod/developers/manifest.xml
+++ b/mod/developers/manifest.xml
@@ -8,7 +8,7 @@
<blurb>Developer tools for Elgg</blurb>
<description>A set of tools for writing plugins and themes. It is recommended that you have this plugin at the top of the plugin list.</description>
<website>http://www.elgg.org/</website>
- <bugtracker>http://trac.elgg.org</bugtracker>
+ <bugtracker>https://github.com/Elgg/Elgg/issues</bugtracker>
<copyright>See COPYRIGHT.txt</copyright>
<license>GNU General Public License version 2</license>
diff --git a/mod/developers/start.php b/mod/developers/start.php
index 413a8ed9b..94d0f652c 100644
--- a/mod/developers/start.php
+++ b/mod/developers/start.php
@@ -89,6 +89,15 @@ function developers_clear_strings() {
/**
* Post-process a view to add wrapper comments to it
+ *
+ * 1. Only process views served with the 'default' viewtype.
+ * 2. Does not wrap views that begin with js/ or css/ as they are not HTML.
+ * 3. Does not wrap views that are images (start with icon/). Is this still true?
+ * 4. Does not wrap input and output views (why?).
+ * 5. Does not wrap html head or the primary page shells
+ *
+ * @warning this will break views in the default viewtype that return non-HTML data
+ * that do not match the above restrictions.
*/
function developers_wrap_views($hook, $type, $result, $params) {
if (elgg_get_viewtype() != "default") {
diff --git a/mod/developers/views/default/theme_preview/components/image_block.php b/mod/developers/views/default/theme_preview/components/image_block.php
index 0bb16428b..ecd35ac65 100644
--- a/mod/developers/views/default/theme_preview/components/image_block.php
+++ b/mod/developers/views/default/theme_preview/components/image_block.php
@@ -1,6 +1,6 @@
-<?php
-$ipsum = elgg_view('developers/ipsum');
-
-$user = new ElggUser();
-$image = elgg_view_entity_icon($user, 'small');
-echo elgg_view_image_block($image, "$ipsum $ipsum $ipsum $ipsum $ipsum $ipsum $ipsum");
+<?php
+$ipsum = elgg_view('developers/ipsum');
+
+$user = new ElggUser();
+$image = elgg_view_entity_icon($user, 'small');
+echo elgg_view_image_block($image, "$ipsum $ipsum $ipsum $ipsum $ipsum $ipsum $ipsum");
diff --git a/mod/developers/views/default/theme_preview/components/list.php b/mod/developers/views/default/theme_preview/components/list.php
index 8096bda04..fcb6f768a 100644
--- a/mod/developers/views/default/theme_preview/components/list.php
+++ b/mod/developers/views/default/theme_preview/components/list.php
@@ -1,19 +1,19 @@
-<?php
-
-$obj1 = new ElggObject();
-$obj1->title = "Object 1";
-$obj1->description = $ipsum;
-
-$obj2 = new ElggObject();
-$obj2->title = "Object 2";
-$obj2->description = $ipsum;
-
-$obj3 = new ElggObject();
-$obj3->title = "Object 3";
-$obj3->description = $ipsum;
-
-$obj4 = new ElggObject();
-$obj4->title = "Object 4";
-$obj4->description = $ipsum;
-
-echo elgg_view('page/components/list', array('items' => array($obj1, $obj2, $obj3, $obj4)));
+<?php
+
+$obj1 = new ElggObject();
+$obj1->title = "Object 1";
+$obj1->description = $ipsum;
+
+$obj2 = new ElggObject();
+$obj2->title = "Object 2";
+$obj2->description = $ipsum;
+
+$obj3 = new ElggObject();
+$obj3->title = "Object 3";
+$obj3->description = $ipsum;
+
+$obj4 = new ElggObject();
+$obj4->title = "Object 4";
+$obj4->description = $ipsum;
+
+echo elgg_view('page/components/list', array('items' => array($obj1, $obj2, $obj3, $obj4)));
diff --git a/mod/developers/views/default/theme_preview/components/messages.php b/mod/developers/views/default/theme_preview/components/messages.php
index ac4d2bfd7..a53255291 100644
--- a/mod/developers/views/default/theme_preview/components/messages.php
+++ b/mod/developers/views/default/theme_preview/components/messages.php
@@ -1,5 +1,5 @@
-<ul>
- <li class="elgg-message elgg-state-success mas">Success message (.elgg-state-success)</li>
- <li class="elgg-message elgg-state-error mas">Error message (.elgg-state-error)</li>
- <li class="elgg-message elgg-state-notice mas">Notice message (.elgg-state-notice)</li>
-</ul>
+<ul>
+ <li class="elgg-message elgg-state-success mas">Success message (.elgg-state-success)</li>
+ <li class="elgg-message elgg-state-error mas">Error message (.elgg-state-error)</li>
+ <li class="elgg-message elgg-state-notice mas">Notice message (.elgg-state-notice)</li>
+</ul>
diff --git a/mod/developers/views/default/theme_preview/components/table.php b/mod/developers/views/default/theme_preview/components/table.php
index 8b8b13e76..7d619dcea 100644
--- a/mod/developers/views/default/theme_preview/components/table.php
+++ b/mod/developers/views/default/theme_preview/components/table.php
@@ -1,12 +1,12 @@
-<table class="<?php echo $vars['class']; ?>">
-<?php
- echo "<thead><tr><th>column 1</th><th>column 2</th></tr></thead>";
- for ($i = 1; $i < 5; $i++) {
- echo '<tr>';
- for ($j = 1; $j < 3; $j++) {
- echo "<td>value $j</td>";
- }
- echo '</tr>';
- }
-?>
+<table class="<?php echo $vars['class']; ?>">
+<?php
+ echo "<thead><tr><th>column 1</th><th>column 2</th></tr></thead>";
+ for ($i = 1; $i < 5; $i++) {
+ echo '<tr>';
+ for ($j = 1; $j < 3; $j++) {
+ echo "<td>value $j</td>";
+ }
+ echo '</tr>';
+ }
+?>
</table> \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/icons/avatars.php b/mod/developers/views/default/theme_preview/icons/avatars.php
index f50a6b70d..3aa1eda26 100644
--- a/mod/developers/views/default/theme_preview/icons/avatars.php
+++ b/mod/developers/views/default/theme_preview/icons/avatars.php
@@ -1,36 +1,36 @@
-<?php
- $user = new ElggUser();
- $group = new ElggGroup();
-
- $sizes = array('large', 'medium', 'small', 'tiny');
-?>
-<table class="elgg-table">
- <tr>
- <th></th>
- <?php
- foreach ($sizes as $size) {
- echo "<th>$size</th>";
- }
- ?>
- </tr>
- <tr>
- <th>User</th>
- <?php
- foreach ($sizes as $size) {
- echo '<td>';
- echo elgg_view_entity_icon($user, $size, array('use_hover' => false));
- echo '</td>';
- }
- ?>
- </tr>
- <tr>
- <th>Group</th>
- <?php
- foreach ($sizes as $size) {
- echo '<td>';
- echo elgg_view_entity_icon($group, $size, array('use_hover' => false));
- echo '</td>';
- }
- ?>
- </tr>
-</table>
+<?php
+ $user = new ElggUser();
+ $group = new ElggGroup();
+
+ $sizes = array('large', 'medium', 'small', 'tiny');
+?>
+<table class="elgg-table">
+ <tr>
+ <th></th>
+ <?php
+ foreach ($sizes as $size) {
+ echo "<th>$size</th>";
+ }
+ ?>
+ </tr>
+ <tr>
+ <th>User</th>
+ <?php
+ foreach ($sizes as $size) {
+ echo '<td>';
+ echo elgg_view_entity_icon($user, $size, array('use_hover' => false));
+ echo '</td>';
+ }
+ ?>
+ </tr>
+ <tr>
+ <th>Group</th>
+ <?php
+ foreach ($sizes as $size) {
+ echo '<td>';
+ echo elgg_view_entity_icon($group, $size, array('use_hover' => false));
+ echo '</td>';
+ }
+ ?>
+ </tr>
+</table>
diff --git a/mod/developers/views/default/theme_preview/icons/sprites.php b/mod/developers/views/default/theme_preview/icons/sprites.php
index 134dd9aca..3edb0bd7c 100644
--- a/mod/developers/views/default/theme_preview/icons/sprites.php
+++ b/mod/developers/views/default/theme_preview/icons/sprites.php
@@ -1,61 +1,61 @@
-<?php
-$icons = array(
- 'arrow-left',
- 'arrow-right',
- 'arrow-two-head',
- 'calendar',
- 'checkmark',
- 'clip',
- 'cursor-drag-arrow',
- 'delete-alt',
- 'delete',
- 'download',
- 'facebook',
- 'home',
- 'hover-menu',
- 'link',
- 'mail-alt',
- 'mail',
- 'print-alt',
- 'print',
- 'push-pin-alt',
- 'push-pin',
- 'redo',
- 'refresh',
- 'round-arrow-left',
- 'round-arrow-right',
- 'round-checkmark',
- 'round-minus',
- 'round-plus',
- 'rss',
- 'search-focus',
- 'search',
- 'settings-alt',
- 'settings',
- 'share',
- 'shop-cart',
- 'speech-bubble-alt',
- 'speech-bubble',
- 'star-alt',
- 'star-empty',
- 'star',
- 'tag',
- 'thumbs-down-alt',
- 'thumbs-down',
- 'thumbs-up-alt',
- 'thumbs-up',
- 'trash',
- 'twitter',
- 'undo',
- 'user',
- 'users',
-);
-?>
-
-<ul class="elgg-gallery">
-<?php
- foreach ($icons as $icon) {
- echo "<li title=\".elgg-icon-$icon\" style=\"margin:10px\">" . elgg_view_icon($icon) . "</li>";
- }
-?>
+<?php
+$icons = array(
+ 'arrow-left',
+ 'arrow-right',
+ 'arrow-two-head',
+ 'calendar',
+ 'checkmark',
+ 'clip',
+ 'cursor-drag-arrow',
+ 'delete-alt',
+ 'delete',
+ 'download',
+ 'facebook',
+ 'home',
+ 'hover-menu',
+ 'link',
+ 'mail-alt',
+ 'mail',
+ 'print-alt',
+ 'print',
+ 'push-pin-alt',
+ 'push-pin',
+ 'redo',
+ 'refresh',
+ 'round-arrow-left',
+ 'round-arrow-right',
+ 'round-checkmark',
+ 'round-minus',
+ 'round-plus',
+ 'rss',
+ 'search-focus',
+ 'search',
+ 'settings-alt',
+ 'settings',
+ 'share',
+ 'shop-cart',
+ 'speech-bubble-alt',
+ 'speech-bubble',
+ 'star-alt',
+ 'star-empty',
+ 'star',
+ 'tag',
+ 'thumbs-down-alt',
+ 'thumbs-down',
+ 'thumbs-up-alt',
+ 'thumbs-up',
+ 'trash',
+ 'twitter',
+ 'undo',
+ 'user',
+ 'users',
+);
+?>
+
+<ul class="elgg-gallery">
+<?php
+ foreach ($icons as $icon) {
+ echo "<li title=\".elgg-icon-$icon\" style=\"margin:10px\">" . elgg_view_icon($icon) . "</li>";
+ }
+?>
</ul> \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/modules/modules.php b/mod/developers/views/default/theme_preview/modules/modules.php
index e0d39c0da..04f5917b4 100644
--- a/mod/developers/views/default/theme_preview/modules/modules.php
+++ b/mod/developers/views/default/theme_preview/modules/modules.php
@@ -1,23 +1,23 @@
-<?php
-
-$ipsum = elgg_view('developers/ipsum');
-
-?>
-<div class="elgg-grid">
- <div class="elgg-col elgg-col-1of2">
- <div class="pam">
- <?php
- echo elgg_view_module('aside', 'Aside (.elgg-module-aside)', $ipsum);
- echo elgg_view_module('popup', 'Popup (.elgg-module-popup)', $ipsum);
- ?>
- </div>
- </div>
- <div class="elgg-col elgg-col-1of2">
- <div class="pam">
- <?php
- echo elgg_view_module('info', 'Info (.elgg-module-info)', $ipsum);
- echo elgg_view_module('featured', 'Featured (.elgg-module-featured)', $ipsum);
- ?>
- </div>
- </div>
+<?php
+
+$ipsum = elgg_view('developers/ipsum');
+
+?>
+<div class="elgg-grid">
+ <div class="elgg-col elgg-col-1of2">
+ <div class="pam">
+ <?php
+ echo elgg_view_module('aside', 'Aside (.elgg-module-aside)', $ipsum);
+ echo elgg_view_module('popup', 'Popup (.elgg-module-popup)', $ipsum);
+ ?>
+ </div>
+ </div>
+ <div class="elgg-col elgg-col-1of2">
+ <div class="pam">
+ <?php
+ echo elgg_view_module('info', 'Info (.elgg-module-info)', $ipsum);
+ echo elgg_view_module('featured', 'Featured (.elgg-module-featured)', $ipsum);
+ ?>
+ </div>
+ </div>
</div> \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/navigation/breadcrumbs.php b/mod/developers/views/default/theme_preview/navigation/breadcrumbs.php
index c910b2aa4..0439bd577 100644
--- a/mod/developers/views/default/theme_preview/navigation/breadcrumbs.php
+++ b/mod/developers/views/default/theme_preview/navigation/breadcrumbs.php
@@ -1,10 +1,10 @@
-<?php
-elgg_push_breadcrumb('First', "#");
-elgg_push_breadcrumb('Second', "#");
-elgg_push_breadcrumb('Third');
-
-echo elgg_view('navigation/breadcrumbs', array('class' => mts));
-
-elgg_pop_breadcrumb();
-elgg_pop_breadcrumb();
-elgg_pop_breadcrumb();
+<?php
+elgg_push_breadcrumb('First', "#");
+elgg_push_breadcrumb('Second', "#");
+elgg_push_breadcrumb('Third');
+
+echo elgg_view('navigation/breadcrumbs', array('class' => mts));
+
+elgg_pop_breadcrumb();
+elgg_pop_breadcrumb();
+elgg_pop_breadcrumb();
diff --git a/mod/developers/views/default/theme_preview/navigation/default.php b/mod/developers/views/default/theme_preview/navigation/default.php
index bfd26162f..6efcd8890 100644
--- a/mod/developers/views/default/theme_preview/navigation/default.php
+++ b/mod/developers/views/default/theme_preview/navigation/default.php
@@ -1,11 +1,11 @@
-<?php
-
-$params = array();
-$params['menu'] = array();
-$params['menu']['default'] = array();
-for ($i=1; $i<=5; $i++) {
- $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "#");
-}
-$params['menu']['default'][2]->setSelected(true);
-
-echo elgg_view('navigation/menu/default', $params);
+<?php
+
+$params = array();
+$params['menu'] = array();
+$params['menu']['default'] = array();
+for ($i=1; $i<=5; $i++) {
+ $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "#");
+}
+$params['menu']['default'][2]->setSelected(true);
+
+echo elgg_view('navigation/menu/default', $params);
diff --git a/mod/developers/views/default/theme_preview/navigation/extras.php b/mod/developers/views/default/theme_preview/navigation/extras.php
index 43b19f8e3..01bc6d434 100644
--- a/mod/developers/views/default/theme_preview/navigation/extras.php
+++ b/mod/developers/views/default/theme_preview/navigation/extras.php
@@ -1,18 +1,18 @@
-<?php
-
-$params = array();
-$params['menu'] = array();
-$params['menu']['default'] = array();
-$params['menu']['default'][] = new ElggMenuItem(1, elgg_view_icon('push-pin-alt'), "#");
-$params['menu']['default'][] = new ElggMenuItem(2, elgg_view_icon('rss'), "#");
-$params['menu']['default'][] = new ElggMenuItem(3, elgg_view_icon('star-alt'), "#");
-$params['name'] = 'extras';
-$params['class'] = 'elgg-menu-hz';
-
-?>
-
-<div class="elgg-sidebar">
-<?php
- echo elgg_view('navigation/menu/default', $params);
-?>
+<?php
+
+$params = array();
+$params['menu'] = array();
+$params['menu']['default'] = array();
+$params['menu']['default'][] = new ElggMenuItem(1, elgg_view_icon('push-pin-alt'), "#");
+$params['menu']['default'][] = new ElggMenuItem(2, elgg_view_icon('rss'), "#");
+$params['menu']['default'][] = new ElggMenuItem(3, elgg_view_icon('star-alt'), "#");
+$params['name'] = 'extras';
+$params['class'] = 'elgg-menu-hz';
+
+?>
+
+<div class="elgg-sidebar">
+<?php
+ echo elgg_view('navigation/menu/default', $params);
+?>
</div> \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/navigation/filter.php b/mod/developers/views/default/theme_preview/navigation/filter.php
index ea1c8b033..70cd31d2a 100644
--- a/mod/developers/views/default/theme_preview/navigation/filter.php
+++ b/mod/developers/views/default/theme_preview/navigation/filter.php
@@ -1,13 +1,13 @@
-<?php
-
-$params = array();
-$params['menu'] = array();
-$params['menu']['default'] = array();
-for ($i=1; $i<=5; $i++) {
- $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "#");
-}
-$params['menu']['default'][2]->setSelected(true);
-
-$params['name'] = 'filter';
-
-echo elgg_view('navigation/menu/default', $params);
+<?php
+
+$params = array();
+$params['menu'] = array();
+$params['menu']['default'] = array();
+for ($i=1; $i<=5; $i++) {
+ $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "#");
+}
+$params['menu']['default'][2]->setSelected(true);
+
+$params['name'] = 'filter';
+
+echo elgg_view('navigation/menu/default', $params);
diff --git a/mod/developers/views/default/theme_preview/navigation/horizontal.php b/mod/developers/views/default/theme_preview/navigation/horizontal.php
index f404f42c0..44e04cd7c 100644
--- a/mod/developers/views/default/theme_preview/navigation/horizontal.php
+++ b/mod/developers/views/default/theme_preview/navigation/horizontal.php
@@ -1,12 +1,12 @@
-<?php
-
-$params = array();
-$params['menu'] = array();
-$params['menu']['default'] = array();
-for ($i=1; $i<=5; $i++) {
- $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "#");
-}
-$params['menu']['default'][2]->setSelected(true);
-$params['class'] = 'elgg-menu-hz';
-
-echo elgg_view('navigation/menu/default', $params);
+<?php
+
+$params = array();
+$params['menu'] = array();
+$params['menu']['default'] = array();
+for ($i=1; $i<=5; $i++) {
+ $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "#");
+}
+$params['menu']['default'][2]->setSelected(true);
+$params['class'] = 'elgg-menu-hz';
+
+echo elgg_view('navigation/menu/default', $params);
diff --git a/mod/developers/views/default/theme_preview/navigation/owner_block.php b/mod/developers/views/default/theme_preview/navigation/owner_block.php
index 20b93d166..f5f203947 100644
--- a/mod/developers/views/default/theme_preview/navigation/owner_block.php
+++ b/mod/developers/views/default/theme_preview/navigation/owner_block.php
@@ -1,13 +1,13 @@
-<?php
-$params = array();
-$params['menu'] = array();
-$params['menu']['default'] = array();
-for ($i=1; $i<=5; $i++) {
- $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "#");
-}
-$params['menu']['default'][2]->setSelected(true);
-$params['name'] = 'owner-block';
-
-echo '<div class="elgg-sidebar">';
-echo elgg_view('navigation/menu/default', $params);
-echo '</div>';
+<?php
+$params = array();
+$params['menu'] = array();
+$params['menu']['default'] = array();
+for ($i=1; $i<=5; $i++) {
+ $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "#");
+}
+$params['menu']['default'][2]->setSelected(true);
+$params['name'] = 'owner-block';
+
+echo '<div class="elgg-sidebar">';
+echo elgg_view('navigation/menu/default', $params);
+echo '</div>';
diff --git a/mod/developers/views/default/theme_preview/navigation/page.php b/mod/developers/views/default/theme_preview/navigation/page.php
index a57edc2e2..1da6a1fd9 100644
--- a/mod/developers/views/default/theme_preview/navigation/page.php
+++ b/mod/developers/views/default/theme_preview/navigation/page.php
@@ -1,20 +1,20 @@
-<?php
-
-$params = array();
-$params['menu'] = array();
-$params['menu']['default'] = array();
-for ($i=1; $i<=5; $i++) {
- $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "#");
-}
-$params['menu']['default'][2]->setSelected(true);
-
-$m = new ElggMenuItem(10, "Child", "#");
-$m->setParent($params['menu']['default'][1]);
-$params['menu']['default'][1]->addChild($m);
-?>
-
-<div class="elgg-sidebar">
-<?php
- echo elgg_view('navigation/menu/page', $params);
-?>
+<?php
+
+$params = array();
+$params['menu'] = array();
+$params['menu']['default'] = array();
+for ($i=1; $i<=5; $i++) {
+ $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "#");
+}
+$params['menu']['default'][2]->setSelected(true);
+
+$m = new ElggMenuItem(10, "Child", "#");
+$m->setParent($params['menu']['default'][1]);
+$params['menu']['default'][1]->addChild($m);
+?>
+
+<div class="elgg-sidebar">
+<?php
+ echo elgg_view('navigation/menu/page', $params);
+?>
</div> \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/navigation/pagination.php b/mod/developers/views/default/theme_preview/navigation/pagination.php
index 90ae48edf..f5e1b632d 100644
--- a/mod/developers/views/default/theme_preview/navigation/pagination.php
+++ b/mod/developers/views/default/theme_preview/navigation/pagination.php
@@ -1,8 +1,8 @@
-<?php
-$params = array(
- 'count' => 1000,
- 'limit' => 10,
- 'offset' => 230,
-);
-
+<?php
+$params = array(
+ 'count' => 1000,
+ 'limit' => 10,
+ 'offset' => 230,
+);
+
echo elgg_view('navigation/pagination', $params); \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/navigation/site.php b/mod/developers/views/default/theme_preview/navigation/site.php
index 329036b80..90bb8ff46 100644
--- a/mod/developers/views/default/theme_preview/navigation/site.php
+++ b/mod/developers/views/default/theme_preview/navigation/site.php
@@ -1,18 +1,18 @@
-<?php
-
-$params = array();
-$params['menu'] = array();
-$params['menu']['default'] = array();
-for ($i=1; $i<=5; $i++) {
- $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "#");
-}
-$params['menu']['default'][2]->setSelected(true);
-?>
-
-<div class="elgg-page-header">
- <div class="elgg-inner">
- <?php
- echo elgg_view('navigation/menu/site', $params);
- ?>
- </div>
-</div>
+<?php
+
+$params = array();
+$params['menu'] = array();
+$params['menu']['default'] = array();
+for ($i=1; $i<=5; $i++) {
+ $params['menu']['default'][] = new ElggMenuItem($i, "Page $i", "#");
+}
+$params['menu']['default'][2]->setSelected(true);
+?>
+
+<div class="elgg-page-header">
+ <div class="elgg-inner">
+ <?php
+ echo elgg_view('navigation/menu/site', $params);
+ ?>
+ </div>
+</div>
diff --git a/mod/developers/views/default/theme_preview/navigation/tabs.php b/mod/developers/views/default/theme_preview/navigation/tabs.php
index 81fe4e669..dd282dc83 100644
--- a/mod/developers/views/default/theme_preview/navigation/tabs.php
+++ b/mod/developers/views/default/theme_preview/navigation/tabs.php
@@ -1,10 +1,10 @@
-<?php
-$params = array(
- 'tabs' => array(
- array('title' => 'First', 'url' => "#"),
- array('title' => 'Second', 'url' => "#", 'selected' => true),
- array('title' => 'Third', 'url' => "#"),
- )
-);
-
+<?php
+$params = array(
+ 'tabs' => array(
+ array('title' => 'First', 'url' => "#"),
+ array('title' => 'Second', 'url' => "#", 'selected' => true),
+ array('title' => 'Third', 'url' => "#"),
+ )
+);
+
echo elgg_view('navigation/tabs', $params); \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/typography/headings.php b/mod/developers/views/default/theme_preview/typography/headings.php
index 1eb96c75c..d843853e3 100644
--- a/mod/developers/views/default/theme_preview/typography/headings.php
+++ b/mod/developers/views/default/theme_preview/typography/headings.php
@@ -1,6 +1,6 @@
-<h1>Level 1 heading</h1>
-<h2>Level 2 heading</h2>
-<h3>Level 3 heading</h3>
-<h4>Level 4 heading</h4>
-<h5>Level 5 heading</h5>
+<h1>Level 1 heading</h1>
+<h2>Level 2 heading</h2>
+<h3>Level 3 heading</h3>
+<h4>Level 4 heading</h4>
+<h5>Level 5 heading</h5>
<h6>Level 6 heading</h6> \ No newline at end of file
diff --git a/mod/developers/views/default/theme_preview/typography/misc.php b/mod/developers/views/default/theme_preview/typography/misc.php
index 93a279c36..0b9fd9db7 100644
--- a/mod/developers/views/default/theme_preview/typography/misc.php
+++ b/mod/developers/views/default/theme_preview/typography/misc.php
@@ -1,16 +1,16 @@
-<ul>
- <li>I am <a href="?abc123">the a tag</a> example</li>
- <li>I am <abbr title="test">the abbr tag</abbr> example</li>
- <li>I am <acronym>the acronym tag</acronym> example</li>
- <li>I am <b>the b tag</b> example</li>
- <li>I am <code>the code tag</code> example</li>
- <li>I am <del>the del tag</del> example</li>
- <li>I am <em>the em tag</em> example</li>
- <li>I am <i>the i tag</i> example</li>
- <li>I am <strong>the strong tag</strong> example</li>
-</ul>
-<blockquote><p>Paragraph inside Blockquote: <?php echo $ipsum; ?></p></blockquote>
-<pre>
- <strong>Preformated:</strong>Testing one row
- and another
-</pre>
+<ul>
+ <li>I am <a href="?abc123">the a tag</a> example</li>
+ <li>I am <abbr title="test">the abbr tag</abbr> example</li>
+ <li>I am <acronym>the acronym tag</acronym> example</li>
+ <li>I am <b>the b tag</b> example</li>
+ <li>I am <code>the code tag</code> example</li>
+ <li>I am <del>the del tag</del> example</li>
+ <li>I am <em>the em tag</em> example</li>
+ <li>I am <i>the i tag</i> example</li>
+ <li>I am <strong>the strong tag</strong> example</li>
+</ul>
+<blockquote><p>Paragraph inside Blockquote: <?php echo $ipsum; ?></p></blockquote>
+<pre>
+ <strong>Preformated:</strong>Testing one row
+ and another
+</pre>
diff --git a/mod/developers/views/default/theme_preview/typography/paragraph.php b/mod/developers/views/default/theme_preview/typography/paragraph.php
index 54d548f46..a3a7b2cfa 100644
--- a/mod/developers/views/default/theme_preview/typography/paragraph.php
+++ b/mod/developers/views/default/theme_preview/typography/paragraph.php
@@ -1,19 +1,19 @@
-<p>Lorem ipsum dolor sit amet, <a href="#" title="test link">test link</a>
-adipiscing elit. Nullam dignissim convallis est. Quisque aliquam. Donec
-faucibus. Nunc iaculis suscipit dui. Nam sit amet sem. Aliquam libero
-nisi, imperdiet at, tincidunt nec, gravida vehicula, nisl. Praesent
-mattis, massa quis luctus <strong>strong</strong>, turpis mi volutpat justo, eu
-volutpat enim diam eget metus. Maecenas ornare tortor. Donec sed tellus
-eget sapien fringilla nonummy. Mauris a ante. Suspendisse quam sem,
-consequat at, commodo vitae, feugiat in, nunc. Morbi imperdiet augue
-quis tellus.</p>
-
-<p>Lorem ipsum dolor sit amet, <em>emphasis</em> consectetuer
-adipiscing elit. Nullam dignissim convallis est. Quisque aliquam. Donec
-faucibus. Nunc iaculis suscipit dui. Nam sit amet sem. Aliquam libero
-nisi, imperdiet at, tincidunt nec, gravida vehicula, nisl. Praesent
-mattis, massa quis luctus fermentum, turpis mi volutpat justo, eu
-volutpat enim diam eget metus. Maecenas ornare tortor. Donec sed tellus
-eget sapien fringilla nonummy. Mauris a ante. Suspendisse quam sem,
-consequat at, commodo vitae, feugiat in, nunc. Morbi imperdiet augue
+<p>Lorem ipsum dolor sit amet, <a href="#" title="test link">test link</a>
+adipiscing elit. Nullam dignissim convallis est. Quisque aliquam. Donec
+faucibus. Nunc iaculis suscipit dui. Nam sit amet sem. Aliquam libero
+nisi, imperdiet at, tincidunt nec, gravida vehicula, nisl. Praesent
+mattis, massa quis luctus <strong>strong</strong>, turpis mi volutpat justo, eu
+volutpat enim diam eget metus. Maecenas ornare tortor. Donec sed tellus
+eget sapien fringilla nonummy. Mauris a ante. Suspendisse quam sem,
+consequat at, commodo vitae, feugiat in, nunc. Morbi imperdiet augue
+quis tellus.</p>
+
+<p>Lorem ipsum dolor sit amet, <em>emphasis</em> consectetuer
+adipiscing elit. Nullam dignissim convallis est. Quisque aliquam. Donec
+faucibus. Nunc iaculis suscipit dui. Nam sit amet sem. Aliquam libero
+nisi, imperdiet at, tincidunt nec, gravida vehicula, nisl. Praesent
+mattis, massa quis luctus fermentum, turpis mi volutpat justo, eu
+volutpat enim diam eget metus. Maecenas ornare tortor. Donec sed tellus
+eget sapien fringilla nonummy. Mauris a ante. Suspendisse quam sem,
+consequat at, commodo vitae, feugiat in, nunc. Morbi imperdiet augue
quis tellus.</p> \ No newline at end of file
diff --git a/mod/embed/start.php b/mod/embed/start.php
index e8a3f8c14..1da35aa46 100644
--- a/mod/embed/start.php
+++ b/mod/embed/start.php
@@ -13,14 +13,19 @@ elgg_register_event_handler('init', 'system', 'embed_init');
*/
function embed_init() {
elgg_extend_view('css/elgg', 'embed/css');
-
- elgg_register_plugin_hook_handler('register', 'menu:longtext', 'embed_longtext_menu');
+ elgg_extend_view('css/admin', 'embed/css');
+
+ if (elgg_is_logged_in()) {
+ elgg_register_plugin_hook_handler('register', 'menu:longtext', 'embed_longtext_menu');
+ }
elgg_register_plugin_hook_handler('register', 'menu:embed', 'embed_select_tab', 1000);
// Page handler for the modal media embed
elgg_register_page_handler('embed', 'embed_page_handler');
- elgg_register_js('elgg.embed', 'js/embed/embed.js', 'footer');
+ $embed_js = elgg_get_simplecache_url('js', 'embed/embed');
+ elgg_register_simplecache_view('js/embed/embed');
+ elgg_register_js('elgg.embed', $embed_js, 'footer');
}
/**
@@ -39,10 +44,12 @@ function embed_longtext_menu($hook, $type, $items, $vars) {
}
$url = 'embed';
- if (elgg_get_page_owner_guid()) {
- $url = 'embed?container_guid=' . elgg_get_page_owner_guid();
+
+ $page_owner = elgg_get_page_owner_entity();
+ if (elgg_instanceof($page_owner, 'group') && $page_owner->isMember()) {
+ $url = 'embed?container_guid=' . $page_owner->getGUID();
}
-
+
$items[] = ElggMenuItem::factory(array(
'name' => 'embed',
'href' => $url,
@@ -95,7 +102,12 @@ function embed_page_handler($page) {
$container_guid = (int)get_input('container_guid');
if ($container_guid) {
- elgg_set_page_owner_guid($container_guid);
+ $container = get_entity($container_guid);
+
+ if (elgg_instanceof($container, 'group') && $container->isMember()) {
+ // embedding inside a group so save file to group files
+ elgg_set_page_owner_guid($container_guid);
+ }
}
echo elgg_view('embed/layout');
diff --git a/mod/externalpages/start.php b/mod/externalpages/start.php
index 74da7f828..f0ffa6b9d 100644
--- a/mod/externalpages/start.php
+++ b/mod/externalpages/start.php
@@ -12,7 +12,7 @@ function expages_init() {
elgg_register_page_handler('terms', 'expages_page_handler');
elgg_register_page_handler('privacy', 'expages_page_handler');
elgg_register_page_handler('expages', 'expages_page_handler');
-
+
// Register public external pages
elgg_register_plugin_hook_handler('public_pages', 'walled_garden', 'expages_public');
@@ -65,7 +65,7 @@ function expages_page_handler($page, $handler) {
$type = strtolower($handler);
$title = elgg_echo("expages:$type");
- $content = elgg_view_title($title);
+ $header = elgg_view_title($title);
$object = elgg_get_entities(array(
'type' => 'object',
@@ -80,11 +80,11 @@ function expages_page_handler($page, $handler) {
$content = elgg_view('expages/wrapper', array('content' => $content));
if (elgg_is_logged_in() || !elgg_get_config('walled_garden')) {
- $body = elgg_view_layout('one_sidebar', array('content' => $content));
+ $body = elgg_view_layout('one_sidebar', array('title' => $title, 'content' => $content));
echo elgg_view_page($title, $body);
} else {
elgg_load_css('elgg.walled_garden');
- $body = elgg_view_layout('walled_garden', array('content' => $content));
+ $body = elgg_view_layout('walled_garden', array('content' => $header . $content));
echo elgg_view_page($title, $body, 'walled_garden');
}
return true;
diff --git a/mod/file/actions/file/upload.php b/mod/file/actions/file/upload.php
index d6dce2528..7ee402121 100644
--- a/mod/file/actions/file/upload.php
+++ b/mod/file/actions/file/upload.php
@@ -71,9 +71,7 @@ $file->title = $title;
$file->description = $desc;
$file->access_id = $access_id;
$file->container_guid = $container_guid;
-
-$tags = explode(",", $tags);
-$file->tags = $tags;
+$file->tags = string_to_tag_array($tags);
// we have a file upload, so process it
if (isset($_FILES['upload']['name']) && !empty($_FILES['upload']['name'])) {
diff --git a/mod/file/pages/file/friends.php b/mod/file/pages/file/friends.php
index f504bdc1f..d55c1e62b 100644
--- a/mod/file/pages/file/friends.php
+++ b/mod/file/pages/file/friends.php
@@ -7,7 +7,7 @@
$owner = elgg_get_page_owner_entity();
if (!$owner) {
- forward('file/all');
+ forward('', '404');
}
elgg_push_breadcrumb(elgg_echo('file'), "file/all");
diff --git a/mod/file/pages/file/owner.php b/mod/file/pages/file/owner.php
index d7f057f2a..99cf62714 100644
--- a/mod/file/pages/file/owner.php
+++ b/mod/file/pages/file/owner.php
@@ -10,7 +10,7 @@ group_gatekeeper();
$owner = elgg_get_page_owner_entity();
if (!$owner) {
- forward('file/all');
+ forward('', '404');
}
elgg_push_breadcrumb(elgg_echo('file'), "file/all");
@@ -39,7 +39,6 @@ $content = elgg_list_entities(array(
'type' => 'object',
'subtype' => 'file',
'container_guid' => $owner->guid,
- 'limit' => 10,
'full_view' => FALSE,
));
if (!$content) {
diff --git a/mod/file/pages/file/world.php b/mod/file/pages/file/world.php
index 8e6c87f26..96c8de785 100644
--- a/mod/file/pages/file/world.php
+++ b/mod/file/pages/file/world.php
@@ -9,14 +9,11 @@ elgg_push_breadcrumb(elgg_echo('file'));
elgg_register_title_button();
-$limit = get_input("limit", 10);
-
$title = elgg_echo('file:all');
$content = elgg_list_entities(array(
'type' => 'object',
'subtype' => 'file',
- 'limit' => $limit,
'full_view' => FALSE
));
if (!$content) {
diff --git a/mod/groups/actions/groups/edit.php b/mod/groups/actions/groups/edit.php
index 632a6412b..f19b90566 100644
--- a/mod/groups/actions/groups/edit.php
+++ b/mod/groups/actions/groups/edit.php
@@ -54,14 +54,16 @@ if ($group_guid && !$group->canEdit()) {
// Assume we can edit or this is a new group
if (sizeof($input) > 0) {
foreach($input as $shortname => $value) {
- // update access collection name ig group name changes
+ // update access collection name if group name changes
if (!$is_new_group && $shortname == 'name' && $value != $group->name) {
- $ac_name = elgg_echo('groups:group') . ": " . $group->name;
+ $group_name = html_entity_decode($value, ENT_QUOTES, 'UTF-8');
+ $ac_name = sanitize_string(elgg_echo('groups:group') . ": " . $group_name);
$acl = get_access_collection($group->group_acl);
if ($acl) {
// @todo Elgg api does not support updating access collection name
$db_prefix = elgg_get_config('dbprefix');
- $query = "UPDATE {$db_prefix}access_collections SET name = '$ac_name'";
+ $query = "UPDATE {$db_prefix}access_collections SET name = '$ac_name'
+ WHERE id = $group->group_acl";
update_data($query);
}
}
@@ -104,7 +106,21 @@ if (!$is_new_group && $new_owner_guid && $new_owner_guid != $old_owner_guid) {
// verify new owner is member and old owner/admin is logged in
if (is_group_member($group_guid, $new_owner_guid) && ($old_owner_guid == $user->guid || $user->isAdmin())) {
$group->owner_guid = $new_owner_guid;
-
+ $group->container_guid = $new_owner_guid;
+
+ $metadata = elgg_get_metadata(array(
+ 'guid' => $group_guid,
+ 'limit' => false,
+ ));
+ if ($metadata) {
+ foreach ($metadata as $md) {
+ if ($md->owner_guid == $old_owner_guid) {
+ $md->owner_guid = $new_owner_guid;
+ $md->save();
+ }
+ }
+ }
+
// @todo Remove this when #4683 fixed
$owner_has_changed = true;
$old_icontime = $group->icontime;
diff --git a/mod/groups/actions/groups/membership/invite.php b/mod/groups/actions/groups/membership/invite.php
index db90ecf3a..a96165b0e 100644
--- a/mod/groups/actions/groups/membership/invite.php
+++ b/mod/groups/actions/groups/membership/invite.php
@@ -7,43 +7,48 @@
$logged_in_user = elgg_get_logged_in_user_entity();
-$user_guid = get_input('user_guid');
-if (!is_array($user_guid)) {
- $user_guid = array($user_guid);
+$user_guids = get_input('user_guid');
+if (!is_array($user_guids)) {
+ $user_guids = array($user_guids);
}
$group_guid = get_input('group_guid');
+$group = get_entity($group_guid);
-if (sizeof($user_guid)) {
- foreach ($user_guid as $u_id) {
- $user = get_entity($u_id);
- $group = get_entity($group_guid);
-
- if ($user && $group && ($group instanceof ElggGroup) && $group->canEdit()) {
-
- if (!check_entity_relationship($group->guid, 'invited', $user->guid)) {
-
- // Create relationship
- add_entity_relationship($group->guid, 'invited', $user->guid);
-
- // Send email
- $url = elgg_normalize_url("groups/invitations/$user->username");
- $result = notify_user($user->getGUID(), $group->owner_guid,
- elgg_echo('groups:invite:subject', array($user->name, $group->name)),
- elgg_echo('groups:invite:body', array(
- $user->name,
- $logged_in_user->name,
- $group->name,
- $url,
- )),
- NULL);
- if ($result) {
- system_message(elgg_echo("groups:userinvited"));
- } else {
- register_error(elgg_echo("groups:usernotinvited"));
- }
- } else {
- register_error(elgg_echo("groups:useralreadyinvited"));
- }
+if (count($user_guids) > 0 && elgg_instanceof($group, 'group') && $group->canEdit()) {
+ foreach ($user_guids as $guid) {
+ $user = get_user($guid);
+ if (!$user) {
+ continue;
+ }
+
+ if (check_entity_relationship($group->guid, 'invited', $user->guid)) {
+ register_error(elgg_echo("groups:useralreadyinvited"));
+ continue;
+ }
+
+ if (check_entity_relationship($user->guid, 'member', $group->guid)) {
+ // @todo add error message
+ continue;
+ }
+
+ // Create relationship
+ add_entity_relationship($group->guid, 'invited', $user->guid);
+
+ // Send notification
+ $url = elgg_normalize_url("groups/invitations/$user->username");
+ $result = notify_user($user->getGUID(), $group->owner_guid,
+ elgg_echo('groups:invite:subject', array($user->name, $group->name)),
+ elgg_echo('groups:invite:body', array(
+ $user->name,
+ $logged_in_user->name,
+ $group->name,
+ $url,
+ )),
+ NULL);
+ if ($result) {
+ system_message(elgg_echo("groups:userinvited"));
+ } else {
+ register_error(elgg_echo("groups:usernotinvited"));
}
}
}
diff --git a/mod/groups/lib/discussion.php b/mod/groups/lib/discussion.php
index ab2fe4849..874e21b2d 100644
--- a/mod/groups/lib/discussion.php
+++ b/mod/groups/lib/discussion.php
@@ -39,9 +39,8 @@ function discussion_handle_list_page($guid) {
elgg_set_page_owner_guid($guid);
$group = get_entity($guid);
- if (!$group) {
- register_error(elgg_echo('group:notfound'));
- forward();
+ if (!elgg_instanceof($group, 'group')) {
+ forward('', '404');
}
elgg_push_breadcrumb($group->name);
diff --git a/mod/groups/lib/groups.php b/mod/groups/lib/groups.php
index 0557d41eb..77d7c09cc 100644
--- a/mod/groups/lib/groups.php
+++ b/mod/groups/lib/groups.php
@@ -255,8 +255,8 @@ function groups_handle_profile_page($guid) {
elgg_push_context('group_profile');
$group = get_entity($guid);
- if (!$group) {
- forward('groups/all');
+ if (!elgg_instanceof($group, 'group')) {
+ forward('', '404');
}
elgg_push_breadcrumb($group->name);
@@ -366,12 +366,15 @@ function groups_handle_members_page($guid) {
elgg_push_breadcrumb($group->name, $group->getURL());
elgg_push_breadcrumb(elgg_echo('groups:members'));
+ $db_prefix = elgg_get_config('dbprefix');
$content = elgg_list_entities_from_relationship(array(
'relationship' => 'member',
'relationship_guid' => $group->guid,
'inverse_relationship' => true,
'type' => 'user',
'limit' => 20,
+ 'joins' => array("JOIN {$db_prefix}users_entity u ON e.guid=u.guid"),
+ 'order_by' => 'u.name ASC',
));
$params = array(
diff --git a/mod/groups/start.php b/mod/groups/start.php
index 46ab0e636..6002a535c 100644
--- a/mod/groups/start.php
+++ b/mod/groups/start.php
@@ -142,6 +142,10 @@ function groups_setup_sidebar_menus() {
$page_owner = elgg_get_page_owner_entity();
if (elgg_in_context('group_profile')) {
+ if (!elgg_instanceof($page_owner, 'group')) {
+ forward('', '404');
+ }
+
if (elgg_is_logged_in() && $page_owner->canEdit() && !$page_owner->isPublicMembership()) {
$url = elgg_get_site_url() . "groups/requests/{$page_owner->getGUID()}";
diff --git a/mod/groups/views/default/forms/groups/edit.php b/mod/groups/views/default/forms/groups/edit.php
index b2860b225..e2dc5455a 100644
--- a/mod/groups/views/default/forms/groups/edit.php
+++ b/mod/groups/views/default/forms/groups/edit.php
@@ -101,7 +101,7 @@ if ($entity && ($owner_guid == elgg_get_logged_in_user_guid() || elgg_is_admin_l
'limit' => 0,
);
- $batch = new ElggBatch('elgg_get_entities', $options);
+ $batch = new ElggBatch('elgg_get_entities_from_relationship', $options);
foreach ($batch as $member) {
$members[$member->guid] = "$member->name (@$member->username)";
}
diff --git a/mod/groups/views/default/groups/css.php b/mod/groups/views/default/groups/css.php
index 39246f856..32dd2b74d 100644
--- a/mod/groups/views/default/groups/css.php
+++ b/mod/groups/views/default/groups/css.php
@@ -9,10 +9,6 @@
.groups-profile > .elgg-image {
margin-right: 10px;
}
-.groups-profile-icon img {
- width: 100%;
- height: auto;
-}
.groups-stats {
background: #eeeeee;
padding: 5px;
diff --git a/mod/groups/views/default/groups/profile/summary.php b/mod/groups/views/default/groups/profile/summary.php
index f1221f19a..3f7496871 100644
--- a/mod/groups/views/default/groups/profile/summary.php
+++ b/mod/groups/views/default/groups/profile/summary.php
@@ -25,7 +25,14 @@ if (!$owner) {
<div class="groups-profile clearfix elgg-image-block">
<div class="elgg-image">
<div class="groups-profile-icon">
- <?php echo elgg_view_entity_icon($group, 'large', array('href' => '')); ?>
+ <?php
+ // we don't force icons to be square so don't set width/height
+ echo elgg_view_entity_icon($group, 'large', array(
+ 'href' => '',
+ 'width' => '',
+ 'height' => '',
+ ));
+ ?>
</div>
<div class="groups-stats">
<p>
diff --git a/mod/groups/views/default/groups/sidebar/my_status.php b/mod/groups/views/default/groups/sidebar/my_status.php
index 5951cbd28..1e4e84b80 100644
--- a/mod/groups/views/default/groups/sidebar/my_status.php
+++ b/mod/groups/views/default/groups/sidebar/my_status.php
@@ -41,7 +41,7 @@ if ($is_owner) {
}
// notification info
-if (elgg_is_active_plugin('notifications')) {
+if (elgg_is_active_plugin('notifications') && $is_member) {
if ($subscribed) {
elgg_register_menu_item('groups:my_status', array(
'name' => 'subscription_status',
diff --git a/mod/groups/views/default/object/groupforumtopic.php b/mod/groups/views/default/object/groupforumtopic.php
index 34e0ee3cc..e6988d16e 100644
--- a/mod/groups/views/default/object/groupforumtopic.php
+++ b/mod/groups/views/default/object/groupforumtopic.php
@@ -73,7 +73,10 @@ if ($full) {
$info = elgg_view_image_block($poster_icon, $list_body);
- $body = elgg_view('output/longtext', array('value' => $topic->description));
+ $body = elgg_view('output/longtext', array(
+ 'value' => $topic->description,
+ 'class' => 'clearfix',
+ ));
echo <<<HTML
$info
diff --git a/mod/htmlawed/start.php b/mod/htmlawed/start.php
index 12b6470a3..25a70a4aa 100644
--- a/mod/htmlawed/start.php
+++ b/mod/htmlawed/start.php
@@ -156,10 +156,8 @@ function htmlawed_tag_post_processor($element, $attributes = false) {
* Runs unit tests for htmlawed
*
* @return array
- * */
+ */
function htmlawed_test($hook, $type, $value, $params) {
- global $CONFIG;
-
$value[] = dirname(__FILE__) . '/tests/tags.php';
return $value;
}
diff --git a/mod/htmlawed/tests/tags.php b/mod/htmlawed/tests/tags.php
index b3914a9d6..05fe829f4 100644
--- a/mod/htmlawed/tests/tags.php
+++ b/mod/htmlawed/tests/tags.php
@@ -1,45 +1,47 @@
<?php
+
/**
* Dupplicated tags in htmlawed
*/
class HtmLawedDuplicateTagsTest extends ElggCoreUnitTest {
- /**
- * Called before each test object.
- */
- public function __construct() {
- parent::__construct();
- }
-
- /**
- * Called before each test method.
- */
- public function setUp() {
- }
-
- /**
- * Called after each test method.
- */
- public function tearDown() {
- // do not allow SimpleTest to interpret Elgg notices as exceptions
- $this->swallowErrors();
- }
-
- /**
- * Called after each test object.
- */
- public function __destruct() {
- elgg_set_ignore_access($this->ia);
- // all __destruct() code should go above here
- parent::__destruct();
- }
-
- public function testNotDuplicateTags() {
- $filter_html = '<ul><li>item</li></ul>';
- set_input('test', $filter_html);
-
- $expected = $filter_html;
- $result = get_input('test');
- $this->assertEqual($result, $expected);
- }
+ /**
+ * Called before each test object.
+ */
+ public function __construct() {
+ parent::__construct();
+ }
+
+ /**
+ * Called before each test method.
+ */
+ public function setUp() {
+
+ }
+
+ /**
+ * Called after each test method.
+ */
+ public function tearDown() {
+ // do not allow SimpleTest to interpret Elgg notices as exceptions
+ $this->swallowErrors();
+ }
+
+ /**
+ * Called after each test object.
+ */
+ public function __destruct() {
+ // all __destruct() code should go above here
+ parent::__destruct();
+ }
+
+ public function testNotDuplicateTags() {
+ $filter_html = '<ul><li>item</li></ul>';
+ set_input('test', $filter_html);
+
+ $expected = $filter_html;
+ $result = get_input('test');
+ $this->assertEqual($result, $expected);
+ }
+
} \ No newline at end of file
diff --git a/mod/logbrowser/views/default/forms/logbrowser/refine.php b/mod/logbrowser/views/default/forms/logbrowser/refine.php
index ebf7f10ed..3d081c9c2 100644
--- a/mod/logbrowser/views/default/forms/logbrowser/refine.php
+++ b/mod/logbrowser/views/default/forms/logbrowser/refine.php
@@ -9,12 +9,12 @@
* @uses $vars['timeupper']
*/
-if (isset($vars['timelower'])) {
+if (isset($vars['timelower']) && $vars['timelower']) {
$lowerval = date('r', $vars['timelower']);
} else {
$lowerval = "";
}
-if (isset($vars['timeupper'])) {
+if (isset($vars['timeupper']) && $vars['timeupper']) {
$upperval = date('r', $vars['timeupper']);
} else {
$upperval = "";
diff --git a/mod/logbrowser/views/default/logbrowser/refine.php b/mod/logbrowser/views/default/logbrowser/refine.php
index 86460c79e..b40f23fa3 100644
--- a/mod/logbrowser/views/default/logbrowser/refine.php
+++ b/mod/logbrowser/views/default/logbrowser/refine.php
@@ -19,7 +19,7 @@ $toggle_link = elgg_view('output/url', array(
));
$form_class = 'elgg-module elgg-module-inline';
-if (!isset($vars['user_guid'])) {
+if (!isset($vars['user_guid']) && !isset($vars['username'])) {
$form_class .= ' hidden';
}
diff --git a/mod/logbrowser/views/default/logbrowser/table.php b/mod/logbrowser/views/default/logbrowser/table.php
index 1223c1456..b08a0c428 100644
--- a/mod/logbrowser/views/default/logbrowser/table.php
+++ b/mod/logbrowser/views/default/logbrowser/table.php
@@ -35,7 +35,7 @@ $log_entries = $vars['log_entries'];
'is_trusted' => true,
));
$user_guid_link = elgg_view('output/url', array(
- 'href' => "admin/overview/logbrowser?user_guid=$user->guid",
+ 'href' => "admin/administer_utilities/logbrowser?user_guid={$user->guid}",
'text' => $user->getGUID(),
'is_trusted' => true,
));
diff --git a/mod/logrotate/languages/en.php b/mod/logrotate/languages/en.php
index 27731d732..d785ad50d 100644
--- a/mod/logrotate/languages/en.php
+++ b/mod/logrotate/languages/en.php
@@ -20,9 +20,10 @@ $english = array(
'logrotate:week' => 'week',
'logrotate:month' => 'month',
'logrotate:year' => 'year',
+ 'logrotate:never' => 'never',
'logrotate:logdeleted' => "Log deleted\n",
- 'logrotate:lognotdeleted' => "Error deleting log\n",
+ 'logrotate:lognotdeleted' => "No logs deleted\n",
);
add_translation("en", $english);
diff --git a/mod/logrotate/start.php b/mod/logrotate/start.php
index 28f14ad14..f67e419bc 100644
--- a/mod/logrotate/start.php
+++ b/mod/logrotate/start.php
@@ -21,8 +21,11 @@ function logrotate_init() {
// Register cron hook for archival of logs
elgg_register_plugin_hook_handler('cron', $period, 'logrotate_archive_cron');
- // Register cron hook for deletion of selected archived logs
- elgg_register_plugin_hook_handler('cron', $delete, 'logrotate_delete_cron');
+
+ if ($delete != 'never') {
+ // Register cron hook for deletion of selected archived logs
+ elgg_register_plugin_hook_handler('cron', $delete, 'logrotate_delete_cron');
+ }
}
/**
@@ -88,34 +91,32 @@ function logrotate_delete_cron($hook, $entity_type, $returnvalue, $params) {
/**
* This function deletes archived copies of the system logs that are older than specified.
*
- * @param int $time_of_delete An offset in seconds from now to delete (useful for log deletion)
+ * @param int $time_of_delete An offset in seconds from now to delete log tables
+ * @return bool Were any log tables deleted
*/
function log_browser_delete_log($time_of_delete) {
global $CONFIG;
- $offset = (int)$time_of_delete;
- $now = time();
-
- $ts = $now - $offset;
-
- $FLAG = 1;
- $result = mysql_query("SHOW TABLES like '{$CONFIG->dbprefix}system_log_%'");
- while ($showtablerow = mysql_fetch_array($result)) {
- //To obtain time of archival
- $log_time = explode("{$CONFIG->dbprefix}system_log_", $showtablerow[0]);
- if ($log_time < $ts) {
- //If the time of archival is before the required offset then delete
- if (!mysql_query("DROP TABLE $showtablerow[0]")) {
- $FLAG = 0;
- }
+ $cutoff = time() - (int)$time_of_delete;
+
+ $deleted_tables = false;
+ $results = get_data("SHOW TABLES like '{$CONFIG->dbprefix}system_log_%'");
+ if ($results) {
+ foreach ($results as $result) {
+ $data = (array)$result;
+ $table_name = array_shift($data);
+ // extract log table rotation time
+ $log_time = str_replace("{$CONFIG->dbprefix}system_log_", '', $table_name);
+ if ($log_time < $cutoff) {
+ if (delete_data("DROP TABLE $table_name") !== false) {
+ // delete_data returns 0 when dropping a table (false for failure)
+ $deleted_tables = true;
+ } else {
+ elgg_log("Failed to delete the log table $table_name", 'ERROR');
+ }
+ }
}
}
- //Check if the appropriate tables have been deleted and return true if yes
- if ($FLAG) {
- return true;
- } else {
- return false;
- }
-
+ return $deleted_tables;
}
diff --git a/mod/logrotate/views/default/plugins/logrotate/settings.php b/mod/logrotate/views/default/plugins/logrotate/settings.php
index bef8b308d..9fd3e08df 100644
--- a/mod/logrotate/views/default/plugins/logrotate/settings.php
+++ b/mod/logrotate/views/default/plugins/logrotate/settings.php
@@ -40,6 +40,7 @@ if (!$delete) {
'weekly' => elgg_echo('logrotate:week'),
'monthly' => elgg_echo('logrotate:month'),
'yearly' => elgg_echo('logrotate:year'),
+ 'never' => elgg_echo('logrotate:never'),
),
'value' => $delete,
));
diff --git a/mod/messageboard/pages/messageboard/owner.php b/mod/messageboard/pages/messageboard/owner.php
index 2c854d4f3..b3e9f45b0 100644
--- a/mod/messageboard/pages/messageboard/owner.php
+++ b/mod/messageboard/pages/messageboard/owner.php
@@ -16,7 +16,6 @@ elgg_push_breadcrumb($page_owner->name, $page_owner->getURL());
$options = array(
'annotations_name' => 'messageboard',
'guid' => $page_owner_guid,
- 'limit' => 10,
'reverse_order_by' => true,
);
diff --git a/mod/messages/start.php b/mod/messages/start.php
index 5503a675a..6d0e82744 100644
--- a/mod/messages/start.php
+++ b/mod/messages/start.php
@@ -51,6 +51,9 @@ function messages_init() {
elgg_register_plugin_hook_handler('notify:entity:message', 'object', 'messages_notification_msg');
register_notification_object('object', 'messages', elgg_echo('messages:new'));
+ // delete messages sent by a user when user is deleted
+ elgg_register_event_handler('delete', 'user', 'messages_purge');
+
// ecml
elgg_register_plugin_hook_handler('get_views', 'ecml', 'messages_ecml_views_hook');
@@ -425,6 +428,39 @@ function messages_user_hover_menu($hook, $type, $return, $params) {
return $return;
}
+/**
+ * Delete messages from a user who is being deleted
+ *
+ * @param string $event Event name
+ * @param string $type Event type
+ * @param ElggUser $user User being deleted
+ */
+function messages_purge($event, $type, $user) {
+
+ if (!$user->getGUID()) {
+ return;
+ }
+
+ // make sure we delete them all
+ $entity_disable_override = access_get_show_hidden_status();
+ access_show_hidden_entities(true);
+ $ia = elgg_set_ignore_access(true);
+
+ $options = array(
+ 'type' => 'object',
+ 'subtype' => 'messages',
+ 'metadata_name' => 'fromId',
+ 'metadata_value' => $user->getGUID(),
+ 'limit' => 0,
+ );
+ $batch = new ElggBatch('elgg_get_entities_from_metadata', $options);
+ foreach ($batch as $e) {
+ $e->delete();
+ }
+
+ elgg_set_ignore_access($ia);
+ access_show_hidden_entities($entity_disable_override);
+}
/**
* Register messages with ECML.
diff --git a/mod/oauth_api/manifest.xml b/mod/oauth_api/manifest.xml
deleted file mode 100644
index 991be6a22..000000000
--- a/mod/oauth_api/manifest.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<plugin_manifest xmlns="http://www.elgg.org/plugin_manifest/1.8">
- <name>OAuth API</name>
- <author>Core developers</author>
- <version>1.8</version>
- <description>Provides OAuth libraries and API support.</description>
- <category>bundled</category>
- <category>api</category>
- <website>http://www.elgg.org/</website>
- <copyright>See COPYRIGHT.txt</copyright>
- <license>GNU General Public License version 2</license>
- <requires>
- <type>elgg_release</type>
- <version>1.8</version>
- </requires>
-
- <conflicts>
- <type>plugin</type>
- <name>oauth_lib</name>
- </conflicts>
- <conflicts>
- <type>php_extension</type>
- <name>oauth</name>
- </conflicts>
-</plugin_manifest>
diff --git a/mod/oauth_api/start.php b/mod/oauth_api/start.php
deleted file mode 100644
index d087a13d1..000000000
--- a/mod/oauth_api/start.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-/**
- * OAuth libs
- *
- * @todo Pull these out into an elgg_oauth lib and use elgg_register_library().
- * @package oauth_api
- */
-
-// require all vendor libraries
-$plugin_path = dirname(__FILE__) . '/vendors/oauth/library';
-require_once "$plugin_path/OAuthDiscovery.php";
-require_once "$plugin_path/OAuthRequest.php";
-require_once "$plugin_path/OAuthRequester.php";
-require_once "$plugin_path/OAuthRequestVerifier.php";
-require_once "$plugin_path/OAuthServer.php";
-
-require_once "$plugin_path/body/OAuthBodyMultipartFormdata.php";
-
-require_once "$plugin_path/store/OAuthStoreAbstract.class.php";
-
-require_once "$plugin_path/signature_method/OAuthSignatureMethod_HMAC_SHA1.php";
-require_once "$plugin_path/signature_method/OAuthSignatureMethod_MD5.php";
-require_once "$plugin_path/signature_method/OAuthSignatureMethod_PLAINTEXT.php";
-require_once "$plugin_path/signature_method/OAuthSignatureMethod_RSA_SHA1.php";
diff --git a/mod/oauth_api/vendors/oauth/LICENSE b/mod/oauth_api/vendors/oauth/LICENSE
deleted file mode 100644
index f64bcd50f..000000000
--- a/mod/oauth_api/vendors/oauth/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License
-
-Copyright (c) 2007-2008 Mediamatic Lab
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE. \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/example/server/INSTALL b/mod/oauth_api/vendors/oauth/example/server/INSTALL
deleted file mode 100644
index 249c85e9d..000000000
--- a/mod/oauth_api/vendors/oauth/example/server/INSTALL
+++ /dev/null
@@ -1,53 +0,0 @@
-In this example I assume that oauth-php lives in /home/john/src/oauth-php
-
-
-1) Create a virtual host and set the DB_DSN VARIABLE to the DSN of your (mysql) database.
-
-Example
-<VirtualHost *>
- ServerAdmin admin@localhost
- ServerName hello.local
- DocumentRoot /home/john/src/oauth-php/example/server/www
-
- UseCanonicalName Off
- ServerSignature On
-
- SetEnv DB_DSN mysql://foo:bar@localhost/oauth_example_server_db
-
- <Directory "home/john/src/oauth-php/example/server/www">
- Options Indexes FollowSymLinks MultiViews
- AllowOverride None
- Order allow,deny
- Allow from all
-
- <IfModule mod_php5.c>
- php_value magic_quotes_gpc 0
- php_value register_globals 0
- php_value session.auto_start 0
- </IfModule>
-
- </Directory>
-</VirtualHost>
-
-
-2) Create the database structure for the server:
-
-# mysql -u foo -p bar -h localhost < /home/john/src/oauth-php/library/store/mysql/mysql.sql
-
-
-
-3) Download and install smarty into the smarty/core/smarty directory:
-
-# cd /home/john/src/oauth-php/example/server/core
-# wget 'http://www.smarty.net/do_download.php?download_file=Smarty-2.6.19.tar.gz'
-# tar zxf Smarty-2.6.19.tar.gz
-# mv Smarty-2.6.19 smarty
-
-
-4) That's it! Point your browser to
-
- http://hello.local/
-
-To get started.
-
-Arjan Scherpenisse <arjan@mediamatic.nl>, July 2008
diff --git a/mod/oauth_api/vendors/oauth/example/server/core/init.php b/mod/oauth_api/vendors/oauth/example/server/core/init.php
deleted file mode 100644
index e5bb9de35..000000000
--- a/mod/oauth_api/vendors/oauth/example/server/core/init.php
+++ /dev/null
@@ -1,127 +0,0 @@
-<?php
-
-/**
- * oauth-php: Example OAuth server
- *
- * Global initialization file for the server, defines some helper
- * functions, required includes, and starts the session.
- *
- * @author Arjan Scherpenisse <arjan@scherpenisse.net>
- *
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-
-/*
- * Simple 'user management'
- */
-define ('USERNAME', 'sysadmin');
-define ('PASSWORD', 'sysadmin');
-
-
-/*
- * Always announce XRDS OAuth discovery
- */
-header('X-XRDS-Location: http://' . $_SERVER['SERVER_NAME'] . '/services.xrds');
-
-
-/*
- * Initialize the database connection
- */
-$info = parse_url(getenv('DB_DSN'));
-($GLOBALS['db_conn'] = mysql_connect($info['host'], $info['user'], $info['pass'])) || die(mysql_error());
-mysql_select_db(basename($info['path']), $GLOBALS['db_conn']) || die(mysql_error());
-unset($info);
-
-
-require_once '../../../library/OAuthServer.php';
-
-/*
- * Initialize OAuth store
- */
-require_once '../../../library/OAuthStore.php';
-OAuthStore::instance('MySQL', array('conn' => $GLOBALS['db_conn']));
-
-
-/*
- * Session
- */
-session_start();
-
-
-/*
- * Template handling
- */
-require_once 'smarty/libs/Smarty.class.php';
-function session_smarty()
-{
- if (!isset($GLOBALS['smarty']))
- {
- $GLOBALS['smarty'] = new Smarty;
- $GLOBALS['smarty']->template_dir = dirname(__FILE__) . '/templates/';
- $GLOBALS['smarty']->compile_dir = dirname(__FILE__) . '/../cache/templates_c';
- }
-
- return $GLOBALS['smarty'];
-}
-
-function assert_logged_in()
-{
- if (empty($_SESSION['authorized']))
- {
- $uri = $_SERVER['REQUEST_URI'];
- header('Location: /logon?goto=' . urlencode($uri));
- }
-}
-
-function assert_request_vars()
-{
- foreach(func_get_args() as $a)
- {
- if (!isset($_REQUEST[$a]))
- {
- header('HTTP/1.1 400 Bad Request');
- echo 'Bad request.';
- exit;
- }
- }
-}
-
-function assert_request_vars_all()
-{
- foreach($_REQUEST as $row)
- {
- foreach(func_get_args() as $a)
- {
- if (!isset($row[$a]))
- {
- header('HTTP/1.1 400 Bad Request');
- echo 'Bad request.';
- exit;
- }
- }
- }
-}
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/example/server/core/templates/inc/footer.tpl b/mod/oauth_api/vendors/oauth/example/server/core/templates/inc/footer.tpl
deleted file mode 100644
index 308b1d01b..000000000
--- a/mod/oauth_api/vendors/oauth/example/server/core/templates/inc/footer.tpl
+++ /dev/null
@@ -1,2 +0,0 @@
-</body>
-</html>
diff --git a/mod/oauth_api/vendors/oauth/example/server/core/templates/inc/header.tpl b/mod/oauth_api/vendors/oauth/example/server/core/templates/inc/header.tpl
deleted file mode 100644
index 5046f54b0..000000000
--- a/mod/oauth_api/vendors/oauth/example/server/core/templates/inc/header.tpl
+++ /dev/null
@@ -1,2 +0,0 @@
-<html>
- <body>
diff --git a/mod/oauth_api/vendors/oauth/example/server/core/templates/index.tpl b/mod/oauth_api/vendors/oauth/example/server/core/templates/index.tpl
deleted file mode 100644
index 7b065537d..000000000
--- a/mod/oauth_api/vendors/oauth/example/server/core/templates/index.tpl
+++ /dev/null
@@ -1,13 +0,0 @@
-{include file='inc/header.tpl'}
-
-<h1>OAuth server</h1>
-Go to:
-
-<ul>
- <li><a href="/logon">Logon</a></li>
- <li><a href="/register">Register your consumer</a></li>
-</ul>
-
-Afterwards, make an OAuth test request to <strong>http://{$smarty.server.name}/hello</strong> to test your connection.</p>
-
-{include file='inc/footer.tpl'}
diff --git a/mod/oauth_api/vendors/oauth/example/server/core/templates/logon.tpl b/mod/oauth_api/vendors/oauth/example/server/core/templates/logon.tpl
deleted file mode 100644
index 5ccd432b5..000000000
--- a/mod/oauth_api/vendors/oauth/example/server/core/templates/logon.tpl
+++ /dev/null
@@ -1,21 +0,0 @@
-{include file='inc/header.tpl'}
-
-<h1>Login</h1>
-
-<form method="post">
- <input type="hidden" name="goto" value="{$smarty.request.goto}" />
-
- <label for="username">User name</label><br />
- <input type="text" name="username" id="username" />
-
- <br /><br />
-
- <label for="password">Password</label><br />
- <input type="text" name="password" id="password" />
-
- <br /><br />
-
- <input type="submit" value="Login" />
-</form>
-
-{include file='inc/footer.tpl'}
diff --git a/mod/oauth_api/vendors/oauth/example/server/core/templates/register.tpl b/mod/oauth_api/vendors/oauth/example/server/core/templates/register.tpl
deleted file mode 100644
index 0e28c1584..000000000
--- a/mod/oauth_api/vendors/oauth/example/server/core/templates/register.tpl
+++ /dev/null
@@ -1,41 +0,0 @@
-{include file='inc/header.tpl'}
-
-<h1>Register server</h1>
-
-<p>Register a server which is gonna act as an identity client.</p>
-
-<form method="post">
-
- <fieldset>
- <legend>About You</legend>
-
- <p>
- <label for="requester_name">Your name</label><br/>
- <input class="text" id="requester_name" name="requester_name" type="text" value="{$consumer.requester_name|default:$smarty.request.requester_name|escape}" />
- </p>
-
- <p>
- <label for="requester_email">Your email address</label><br/>
- <input class="text" id="requester_email" name="requester_email" type="text" value="{$consumer.requester_email|default:$smarty.request.requester_email|escape}" />
- </p>
- </fieldset>
-
- <fieldset>
- <legend>Location Of Your Application Or Site</legend>
-
- <p>
- <label for="application_uri">URL of your application or site</label><br/>
- <input id="application_uri" class="text" name="application_uri" type="text" value="{$consumer.application_uri|default:$smarty.request.application_uri|escape}" />
- </p>
-
- <p>
- <label for="callback_uri">Callback URL</label><br/>
- <input id="callback_uri" class="text" name="callback_uri" type="text" value="{$consumer.callback_uri|default:$smarty.request.callback_uri|escape}" />
- </p>
- </fieldset>
-
- <br />
- <input type="submit" value="Register server" />
-</form>
-
-{include file='inc/footer.tpl'}
diff --git a/mod/oauth_api/vendors/oauth/example/server/www/hello.php b/mod/oauth_api/vendors/oauth/example/server/www/hello.php
deleted file mode 100644
index 8cb94bb1e..000000000
--- a/mod/oauth_api/vendors/oauth/example/server/www/hello.php
+++ /dev/null
@@ -1,65 +0,0 @@
-<?php
-
-/**
- * oauth-php: Example OAuth server
- *
- * An example service, http://hostname/hello. You will only get the
- * 'Hello, world!' string back if you have signed your request with
- * oauth.
- *
- * @author Arjan Scherpenisse <arjan@scherpenisse.net>
- *
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require_once '../core/init.php';
-
-$authorized = false;
-$server = new OAuthServer();
-try
-{
- if ($server->verifyIfSigned())
- {
- $authorized = true;
- }
-}
-catch (OAuthException $e)
-{
-}
-
-if (!$authorized)
-{
- header('HTTP/1.1 401 Unauthorized');
- header('Content-Type: text/plain');
-
- echo "OAuth Verification Failed: " . $e->getMessage();
- die;
-}
-
-// From here on we are authenticated with OAuth.
-
-header('Content-type: text/plain');
-echo 'Hello, world!';
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/example/server/www/index.php b/mod/oauth_api/vendors/oauth/example/server/www/index.php
deleted file mode 100644
index f5cadbe61..000000000
--- a/mod/oauth_api/vendors/oauth/example/server/www/index.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-/**
- * oauth-php: Example OAuth server
- *
- * @author Arjan Scherpenisse <arjan@scherpenisse.net>
- *
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require '../core/init.php';
-
-$smarty = session_smarty();
-$smarty->display('index.tpl');
-
-?>
diff --git a/mod/oauth_api/vendors/oauth/example/server/www/logon.php b/mod/oauth_api/vendors/oauth/example/server/www/logon.php
deleted file mode 100644
index 5c937b719..000000000
--- a/mod/oauth_api/vendors/oauth/example/server/www/logon.php
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-
-/**
- * oauth-php: Example OAuth server
- *
- * Simple logon for consumer registration at this server.
- *
- * @author Arjan Scherpenisse <arjan@scherpenisse.net>
- *
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require_once '../core/init.php';
-
-if (isset($_POST['username']) && isset($_POST['password']))
-{
- if ($_POST['username'] == USERNAME && $_POST['password'] == PASSWORD)
- {
- $_SESSION['authorized'] = true;
- if (!empty($_REQUEST['goto']))
- {
- header('Location: ' . $_REQUEST['goto']);
- die;
- }
-
- echo "Logon succesfull.";
- die;
- }
-}
-
-$smarty = session_smarty();
-$smarty->display('logon.tpl');
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/example/server/www/oauth.php b/mod/oauth_api/vendors/oauth/example/server/www/oauth.php
deleted file mode 100644
index e0badcc39..000000000
--- a/mod/oauth_api/vendors/oauth/example/server/www/oauth.php
+++ /dev/null
@@ -1,77 +0,0 @@
-<?php
-
-/**
- * oauth-php: Example OAuth server
- *
- * This file implements the OAuth server endpoints. The most basic
- * implementation of an OAuth server.
- *
- * Call with: /oauth/request_token, /oauth/authorize, /oauth/access_token
- *
- * @author Arjan Scherpenisse <arjan@scherpenisse.net>
- *
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require_once '../core/init.php';
-
-$server = new OAuthServer();
-
-switch($_SERVER['PATH_INFO'])
-{
-case '/request_token':
- $server->requestToken();
- exit;
-
-case '/access_token':
- $server->accessToken();
- exit;
-
-case '/authorize':
- # logon
-
- assert_logged_in();
-
- try
- {
- $server->authorizeVerify();
- $server->authorizeFinish(true, 1);
- }
- catch (OAuthException $e)
- {
- header('HTTP/1.1 400 Bad Request');
- header('Content-Type: text/plain');
-
- echo "Failed OAuth Request: " . $e->getMessage();
- }
- exit;
-
-
-default:
- header('HTTP/1.1 500 Internal Server Error');
- header('Content-Type: text/plain');
- echo "Unknown request";
-}
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/example/server/www/register.php b/mod/oauth_api/vendors/oauth/example/server/www/register.php
deleted file mode 100644
index c5785c2c8..000000000
--- a/mod/oauth_api/vendors/oauth/example/server/www/register.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-
-require_once '../core/init.php';
-
-assert_logged_in();
-
-if ($_SERVER['REQUEST_METHOD'] == 'POST')
-{
- try
- {
- $store = OAuthStore::instance();
- $key = $store->updateConsumer($_POST, 1, true);
-
- $c = $store->getConsumer($key);
- echo 'Your consumer key is: <strong>' . $c['consumer_key'] . '</strong><br />';
- echo 'Your consumer secret is: <strong>' . $c['consumer_secret'] . '</strong><br />';
- }
- catch (OAuthException $e)
- {
- echo '<strong>Error: ' . $e->getMessage() . '</strong><br />';
- }
-}
-
-
-$smarty = session_smarty();
-$smarty->display('register.tpl');
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/example/server/www/services.xrds.php b/mod/oauth_api/vendors/oauth/example/server/www/services.xrds.php
deleted file mode 100644
index 4c50aa12b..000000000
--- a/mod/oauth_api/vendors/oauth/example/server/www/services.xrds.php
+++ /dev/null
@@ -1,71 +0,0 @@
-<?php
-
-/**
- * oauth-php: Example OAuth server
- *
- * XRDS discovery for OAuth. This file helps the consumer program to
- * discover where the OAuth endpoints for this server are.
- *
- * @author Arjan Scherpenisse <arjan@scherpenisse.net>
- *
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-header('Content-Type: application/xrds+xml');
-
-$server = $_SERVER['SERVER_NAME'];
-
-echo '<?xml version="1.0" encoding="utf-8"?>' . "\n";
-
-?>
-<XRDS xmlns="xri://$xrds">
- <XRD xmlns:simple="http://xrds-simple.net/core/1.0" xmlns="xri://$XRD*($v*2.0)" xmlns:openid="http://openid.net/xmlns/1.0" version="2.0" xml:id="main">
- <Type>xri://$xrds*simple</Type>
- <Service>
- <Type>http://oauth.net/discovery/1.0</Type>
- <URI>#main</URI>
- </Service>
- <Service>
- <Type>http://oauth.net/core/1.0/endpoint/request</Type>
- <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
- <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
- <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
- <Type>http://oauth.net/core/1.0/signature/PLAINTEXT</Type>
- <URI>http://<?=$server?>/oauth/request_token</URI>
- </Service>
- <Service>
- <Type>http://oauth.net/core/1.0/endpoint/authorize</Type>
- <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
- <URI>http://<?=$server?>/oauth/authorize</URI>
- </Service>
- <Service>
- <Type>http://oauth.net/core/1.0/endpoint/access</Type>
- <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
- <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
- <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
- <Type>http://oauth.net/core/1.0/signature/PLAINTEXT</Type>
- <URI>http://<?=$server?>/oauth/access_token</URI>
- </Service>
- </XRD>
-</XRDS>
diff --git a/mod/oauth_api/vendors/oauth/library/OAuthDiscovery.php b/mod/oauth_api/vendors/oauth/library/OAuthDiscovery.php
deleted file mode 100644
index d097756dd..000000000
--- a/mod/oauth_api/vendors/oauth/library/OAuthDiscovery.php
+++ /dev/null
@@ -1,226 +0,0 @@
-<?php
-
-/**
- * Handle the discovery of OAuth service provider endpoints and static consumer identity.
- *
- * @version $Id$
- * @author Marc Worrell <marcw@pobox.com>
- * @date Sep 4, 2008 5:05:19 PM
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require_once dirname(__FILE__).'/discovery/xrds_parse.php';
-
-require_once dirname(__FILE__).'/OAuthException.php';
-require_once dirname(__FILE__).'/OAuthRequestLogger.php';
-
-
-class OAuthDiscovery
-{
- /**
- * Return a description how we can do a consumer allocation. Prefers static allocation if
- * possible. If static allocation is possible
- *
- * See also: http://oauth.net/discovery/#consumer_identity_types
- *
- * @param string uri
- * @return array provider description
- */
- static function discover ( $uri )
- {
- // See what kind of consumer allocations are available
- $xrds_file = self::discoverXRDS($uri);
- if (!empty($xrds_file))
- {
- $xrds = xrds_parse($xrds_file);
- if (empty($xrds))
- {
- throw new OAuthException('Could not discover OAuth information for '.$uri);
- }
- }
- else
- {
- throw new OAuthException('Could not discover XRDS file at '.$uri);
- }
-
- // Fill an OAuthServer record for the uri found
- $ps = parse_url($uri);
- $host = isset($ps['host']) ? $ps['host'] : 'localhost';
- $server_uri = $ps['scheme'].'://'.$host.'/';
-
- $p = array(
- 'user_id' => null,
- 'consumer_key' => '',
- 'consumer_secret' => '',
- 'signature_methods' => '',
- 'server_uri' => $server_uri,
- 'request_token_uri' => '',
- 'authorize_uri' => '',
- 'access_token_uri' => ''
- );
-
-
- // Consumer identity (out of bounds or static)
- if (isset($xrds['consumer_identity']))
- {
- // Try to find a static consumer allocation, we like those :)
- foreach ($xrds['consumer_identity'] as $ci)
- {
- if ($ci['method'] == 'static' && !empty($ci['consumer_key']))
- {
- $p['consumer_key'] = $ci['consumer_key'];
- $p['consumer_secret'] = '';
- }
- else if ($ci['method'] == 'oob' && !empty($ci['uri']))
- {
- // TODO: Keep this uri somewhere for the user?
- $p['consumer_oob_uri'] = $ci['uri'];
- }
- }
- }
-
- // The token uris
- if (isset($xrds['request'][0]['uri']))
- {
- $p['request_token_uri'] = $xrds['request'][0]['uri'];
- if (!empty($xrds['request'][0]['signature_method']))
- {
- $p['signature_methods'] = $xrds['request'][0]['signature_method'];
- }
- }
- if (isset($xrds['authorize'][0]['uri']))
- {
- $p['authorize_uri'] = $xrds['authorize'][0]['uri'];
- if (!empty($xrds['authorize'][0]['signature_method']))
- {
- $p['signature_methods'] = $xrds['authorize'][0]['signature_method'];
- }
- }
- if (isset($xrds['access'][0]['uri']))
- {
- $p['access_token_uri'] = $xrds['access'][0]['uri'];
- if (!empty($xrds['access'][0]['signature_method']))
- {
- $p['signature_methods'] = $xrds['access'][0]['signature_method'];
- }
- }
- return $p;
- }
-
-
- /**
- * Discover the XRDS file at the uri. This is a bit primitive, you should overrule
- * this function so that the XRDS file can be cached for later referral.
- *
- * @param string uri
- * @return string false when no XRDS file found
- */
- static protected function discoverXRDS ( $uri, $recur = 0 )
- {
- // Bail out when we are following redirects
- if ($recur > 10)
- {
- return false;
- }
-
- $data = self::curl($uri);
-
- // Check what we got back, could be:
- // 1. The XRDS discovery file itself (check content-type)
- // 2. The X-XRDS-Location header
-
- if (is_string($data) && !empty($data))
- {
- list($head,$body) = explode("\r\n\r\n", $data);
- $body = trim($body);
- $m = false;
-
- // See if we got the XRDS file itself or we have to follow a location header
- if ( preg_match('/^Content-Type:\s*application\/xrds+xml/im', $head)
- || preg_match('/^<\?xml[^>]*\?>\s*<xrds\s/i', $body)
- || preg_match('/^<xrds\s/i', $body)
- )
- {
- $xrds = $body;
- }
- else if ( preg_match('/^X-XRDS-Location:\s*(.*)$/im', $head, $m)
- || preg_match('/^Location:\s*(.*)$/im', $head, $m))
- {
- // Recurse to the given location
- if ($uri != $m[1])
- {
- $xrds = self::discoverXRDS($m[1], $recur+1);
- }
- else
- {
- // Referring to the same uri, bail out
- $xrds = false;
- }
- }
- else
- {
- // Not an XRDS file an nowhere else to check
- $xrds = false;
- }
- }
- else
- {
- $xrds = false;
- }
- return $xrds;
- }
-
-
- /**
- * Try to fetch an XRDS file at the given location. Sends an accept header preferring the xrds file.
- *
- * @param string uri
- * @return array (head,body), false on an error
- */
- static protected function curl ( $uri )
- {
- $ch = curl_init();
-
- curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/xrds+xml, */*;q=0.1'));
- curl_setopt($ch, CURLOPT_USERAGENT, 'anyMeta/OAuth 1.0 - (OAuth Discovery $LastChangedRevision: 45 $)');
- curl_setopt($ch, CURLOPT_URL, $uri);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_HEADER, true);
-
- $txt = curl_exec($ch);
- curl_close($ch);
-
- // Tell the logger what we requested and what we received back
- $data = "GET $uri";
- OAuthRequestLogger::setSent($data, "");
- OAuthRequestLogger::setReceived($txt);
-
- return $txt;
- }
-}
-
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/OAuthException.php b/mod/oauth_api/vendors/oauth/library/OAuthException.php
deleted file mode 100644
index cadd1d032..000000000
--- a/mod/oauth_api/vendors/oauth/library/OAuthException.php
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php
-
-/**
- * Simple exception wrapper for OAuth
- *
- * @version $Id: OAuthException.php 49 2008-10-01 09:43:19Z marcw@pobox.com $
- * @author Marc Worrell <marcw@pobox.com>
- * @date Nov 29, 2007 5:33:54 PM
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-// TODO: something with the HTTP return code matching to the problem
-
-require_once dirname(__FILE__) . '/OAuthRequestLogger.php';
-
-class OAuthException extends Exception
-{
- function __construct ( $message )
- {
- Exception::__construct($message);
- OAuthRequestLogger::addNote('OAuthException: '.$message);
- }
-
-}
-
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/OAuthRequest.php b/mod/oauth_api/vendors/oauth/library/OAuthRequest.php
deleted file mode 100644
index c0d6ddbc7..000000000
--- a/mod/oauth_api/vendors/oauth/library/OAuthRequest.php
+++ /dev/null
@@ -1,801 +0,0 @@
-<?php
-
-/**
- * Request wrapper class. Prepares a request for consumption by the OAuth routines
- *
- * @version $Id: OAuthRequest.php 50 2008-10-01 15:11:08Z marcw@pobox.com $
- * @author Marc Worrell <marcw@pobox.com>
- * @date Nov 16, 2007 12:20:31 PM
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-
-require_once dirname(__FILE__) . '/OAuthException.php';
-
-/**
- * Object to parse an incoming OAuth request or prepare an outgoing OAuth request
- */
-class OAuthRequest
-{
- /* the realm for this request */
- protected $realm;
-
- /* all the parameters, RFC3986 encoded name/value pairs */
- protected $param = array();
-
- /* the parsed request uri */
- protected $uri_parts;
-
- /* the raw request uri */
- protected $uri;
-
- /* the request headers */
- protected $headers;
-
- /* the request method */
- protected $method;
-
- /* the body of the OAuth request */
- protected $body;
-
-
- /**
- * Construct from the current request. Useful for checking the signature of a request.
- * When not supplied with any parameters this will use the current request.
- *
- * @param string uri might include parameters
- * @param string method GET, PUT, POST etc.
- * @param string parameters additional post parameters, urlencoded (RFC1738)
- * @param array headers headers for request
- * @param string body optional body of the OAuth request (POST or PUT)
- */
- function __construct ( $uri = null, $method = 'GET', $parameters = '', $headers = array(), $body = null )
- {
- if (empty($uri))
- {
- if (is_object($_SERVER))
- {
- // Tainted arrays - the normal stuff in anyMeta
- $method = $_SERVER->REQUEST_METHOD->getRawUnsafe();
- $uri = $_SERVER->REQUEST_URI->getRawUnsafe();
- }
- else
- {
- // non anyMeta systems
- $method = $_SERVER['REQUEST_METHOD'];
- $uri = $_SERVER['REQUEST_URI'];
- }
- $headers = getallheaders();
- $parameters = '';
- $this->method = strtoupper($method);
-
- // If this is a post then also check the posted variables
- if (strcasecmp($method, 'POST') == 0)
- {
- /*
- // TODO: what to do with 'multipart/form-data'?
- if ($this->getRequestContentType() == 'multipart/form-data')
- {
- throw new OAuthException('Unsupported POST content type, expected "application/x-www-form-urlencoded" got "'.@$_SERVER['CONTENT_TYPE'].'"');
- }
- */
- if ($this->getRequestContentType() == 'application/x-www-form-urlencoded')
- {
- // Get the posted body (when available)
- if (!isset($headers['X-OAuth-Test']))
- {
- $parameters .= $this->getRequestBody();
- }
- }
- else
- {
- $body = $this->getRequestBody();
- }
- }
- else if (strcasecmp($method, 'PUT') == 0)
- {
- $body = $this->getRequestBody();
- }
- }
-
- $this->method = strtoupper($method);
- $this->headers = $headers;
- // Store the values, prepare for oauth
- $this->uri = $uri;
- $this->body = $body;
- $this->parseUri($parameters);
- $this->parseHeaders();
- $this->transcodeParams();
- }
-
-
- /**
- * Return the signature base string.
- * Note that we can't use rawurlencode due to specified use of RFC3986.
- *
- * @return string
- */
- function signatureBaseString ()
- {
- $sig = array();
- $sig[] = $this->method;
- $sig[] = $this->getRequestUrl();
- $sig[] = $this->getNormalizedParams();
-
- return implode('&', array_map(array($this, 'urlencode'), $sig));
- }
-
-
- /**
- * Calculate the signature of the request, using the method in oauth_signature_method.
- * The signature is returned encoded in the form as used in the url. So the base64 and
- * urlencoding has been done.
- *
- * @param string consumer_secret
- * @param string token_secret
- * @exception when not all parts available
- * @return string
- */
- function calculateSignature ( $consumer_secret, $token_secret, $token_type = 'access' )
- {
- $required = array(
- 'oauth_consumer_key',
- 'oauth_signature_method',
- 'oauth_timestamp',
- 'oauth_nonce'
- );
-
- if ($token_type !== false)
- {
- $required[] = 'oauth_token';
- }
-
- foreach ($required as $req)
- {
- if (!isset($this->param[$req]))
- {
- throw new OAuthException('Can\'t sign request, missing parameter "'.$req.'"');
- }
- }
-
- $this->checks();
-
- $base = $this->signatureBaseString();
- $signature = $this->calculateDataSignature($base, $consumer_secret, $token_secret, $this->param['oauth_signature_method']);
- return $signature;
- }
-
-
- /**
- * Calculate the signature of a string.
- * Uses the signature method from the current parameters.
- *
- * @param string data
- * @param string consumer_secret
- * @param string token_secret
- * @param string signature_method
- * @exception OAuthException thrown when the signature method is unknown
- * @return string signature
- */
- function calculateDataSignature ( $data, $consumer_secret, $token_secret, $signature_method )
- {
- if (is_null($data))
- {
- $data = '';
- }
-
- $sig = $this->getSignatureMethod($signature_method);
- return $sig->signature($this, $data, $consumer_secret, $token_secret);
- }
-
-
- /**
- * Select a signature method from the list of available methods.
- * We try to check the most secure methods first.
- *
- * @todo Let the signature method tell us how secure it is
- * @param array methods
- * @exception OAuthException when we don't support any method in the list
- * @return string
- */
- public function selectSignatureMethod ( $methods )
- {
- if (in_array('HMAC-SHA1', $methods))
- {
- $method = 'HMAC-SHA1';
- }
- else if (in_array('MD5', $methods))
- {
- $method = 'MD5';
- }
- else
- {
- $method = false;
- foreach ($methods as $m)
- {
- $m = strtoupper($m);
- $m = preg_replace('/[^A-Z0-9]/', '_', $m);
- if (file_exists(dirname(__FILE__).'/signature_method/OAuthSignatureMethod_'.$m.'.php'))
- {
- $method = $m;
- break;
- }
- }
-
- if (empty($method))
- {
- throw new OAuthException('None of the signing methods is supported.');
- }
- }
- return $method;
- }
-
-
- /**
- * Fetch the signature object used for calculating and checking the signature base string
- *
- * @param string method
- * @return OAuthSignatureMethod object
- */
- function getSignatureMethod ( $method )
- {
- $m = strtoupper($method);
- $m = preg_replace('/[^A-Z0-9]/', '_', $m);
- $class = 'OAuthSignatureMethod_'.$m;
-
- if (file_exists(dirname(__FILE__).'/signature_method/'.$class.'.php'))
- {
- require_once dirname(__FILE__).'/signature_method/'.$class.'.php';
- $sig = new $class();
- }
- else
- {
- throw new OAuthException('Unsupported signature method "'.$m.'".');
- }
- return $sig;
- }
-
-
- /**
- * Perform some sanity checks.
- *
- * @exception OAuthException thrown when sanity checks failed
- */
- function checks ()
- {
- if (isset($this->param['oauth_version']))
- {
- $version = $this->urldecode($this->param['oauth_version']);
- if ($version != '1.0')
- {
- throw new OAuthException('Expected OAuth version 1.0, got "'.$this->param['oauth_version'].'"');
- }
- }
- }
-
-
- /**
- * Return the request method
- *
- * @return string
- */
- function getMethod ()
- {
- return $this->method;
- }
-
- /**
- * Return the complete parameter string for the signature check.
- * All parameters are correctly urlencoded and sorted on name and value
- *
- * @return string
- */
- function getNormalizedParams ()
- {
- /*
- // sort by name, then by value
- // (needed when we start allowing multiple values with the same name)
- $keys = array_keys($this->param);
- $values = array_values($this->param);
- array_multisort($keys, SORT_ASC, $values, SORT_ASC);
- */
- $params = $this->param;
- $normalized = array();
-
- ksort($params);
- foreach ($params as $key => $value)
- {
- // all names and values are already urlencoded, exclude the oauth signature
- if ($key != 'oauth_signature')
- {
- if (is_array($value))
- {
- $value_sort = $value;
- sort($value_sort);
- foreach ($value_sort as $v)
- {
- $normalized[] = $key.'='.$v;
- }
- }
- else
- {
- $normalized[] = $key.'='.$value;
- }
- }
- }
- return implode('&', $normalized);
- }
-
-
- /**
- * Return the normalised url for signature checks
- */
- function getRequestUrl ()
- {
- $url = $this->uri_parts['scheme'] . '://'
- . $this->uri_parts['user'] . (!empty($this->uri_parts['pass']) ? ':' : '')
- . $this->uri_parts['pass'] . (!empty($this->uri_parts['user']) ? '@' : '')
- . $this->uri_parts['host'];
-
- if ( $this->uri_parts['port']
- && $this->uri_parts['port'] != $this->defaultPortForScheme($this->uri_parts['scheme']))
- {
- $url .= ':'.$this->uri_parts['port'];
- }
- if (!empty($this->uri_parts['path']))
- {
- $url .= $this->uri_parts['path'];
- }
- return $url;
- }
-
-
- /**
- * Get a parameter, value is always urlencoded
- *
- * @param string name
- * @param boolean urldecode set to true to decode the value upon return
- * @return string value false when not found
- */
- function getParam ( $name, $urldecode = false )
- {
- if (isset($this->param[$name]))
- {
- $s = $this->param[$name];
- }
- else if (isset($this->param[$this->urlencode($name)]))
- {
- $s = $this->param[$this->urlencode($name)];
- }
- else
- {
- $s = false;
- }
- if (!empty($s) && $urldecode)
- {
- if (is_array($s))
- {
- $s = array_map(array($this,'urldecode'), $s);
- }
- else
- {
- $s = $this->urldecode($s);
- }
- }
- return $s;
- }
-
- /**
- * Set a parameter
- *
- * @param string name
- * @param string value
- * @param boolean encoded set to true when the values are already encoded
- */
- function setParam ( $name, $value, $encoded = false )
- {
- if (!$encoded)
- {
- $name_encoded = $this->urlencode($name);
- if (is_array($value))
- {
- foreach ($value as $v)
- {
- $this->param[$name_encoded][] = $this->urlencode($v);
- }
- }
- else
- {
- $this->param[$name_encoded] = $this->urlencode($value);
- }
- }
- else
- {
- $this->param[$name] = $value;
- }
- }
-
-
- /**
- * Re-encode all parameters so that they are encoded using RFC3986.
- * Updates the $this->param attribute.
- */
- protected function transcodeParams ()
- {
- $params = $this->param;
- $this->param = array();
-
- foreach ($params as $name=>$value)
- {
- if (is_array($value))
- {
- $this->param[$this->urltranscode($name)] = array_map(array($this,'urltranscode'), $value);
- }
- else
- {
- $this->param[$this->urltranscode($name)] = $this->urltranscode($value);
- }
- }
- }
-
-
-
- /**
- * Return the body of the OAuth request.
- *
- * @return string null when no body
- */
- function getBody ()
- {
- return $this->body;
- }
-
-
- /**
- * Return the body of the OAuth request.
- *
- * @return string null when no body
- */
- function setBody ( $body )
- {
- $this->body = $body;
- }
-
-
- /**
- * Parse the uri into its parts. Fill in the missing parts.
- *
- * @todo check for the use of https, right now we default to http
- * @todo support for multiple occurences of parameters
- * @param string $parameters optional extra parameters (from eg the http post)
- */
- protected function parseUri ( $parameters )
- {
- $ps = parse_url($this->uri);
-
- // Get the current/requested method
- if (empty($ps['scheme']))
- {
- $ps['scheme'] = 'http';
- }
- else
- {
- $ps['scheme'] = strtolower($ps['scheme']);
- }
-
- // Get the current/requested host
- if (empty($ps['host']))
- {
- if (isset($_SERVER['HTTP_HOST']))
- {
- $ps['host'] = $_SERVER['HTTP_HOST'];
- }
- else
- {
- $ps['host'] = '';
- }
- }
- $ps['host'] = mb_strtolower($ps['host']);
- if (!preg_match('/^[a-z0-9\.\-]+$/', $ps['host']))
- {
- throw new OAuthException('Unsupported characters in host name');
- }
-
- // Get the port we are talking on
- if (empty($ps['port']))
- {
- $ps['port'] = $this->defaultPortForScheme($ps['scheme']);
- }
-
- if (empty($ps['user']))
- {
- $ps['user'] = '';
- }
- if (empty($ps['pass']))
- {
- $ps['pass'] = '';
- }
- if (empty($ps['path']))
- {
- $ps['path'] = '/';
- }
- if (empty($ps['query']))
- {
- $ps['query'] = '';
- }
- if (empty($ps['fragment']))
- {
- $ps['fragment'] = '';
- }
-
- // Now all is complete - parse all parameters
- foreach (array($ps['query'], $parameters) as $params)
- {
- if (strlen($params) > 0)
- {
- $params = explode('&', $params);
- foreach ($params as $p)
- {
- @list($name, $value) = explode('=', $p, 2);
- $this->param[$name] = $value;
- }
- }
- }
- $this->uri_parts = $ps;
- }
-
-
- /**
- * Return the default port for a scheme
- *
- * @param string scheme
- * @return int
- */
- protected function defaultPortForScheme ( $scheme )
- {
- switch ($scheme)
- {
- case 'http': return 80;
- case 'https': return 43;
- default:
- throw new OAuthException('Unsupported scheme type, expected http or https, got "'.$scheme.'"');
- break;
- }
- }
-
-
- /**
- * Encode a string according to the RFC3986
- *
- * @param string s
- * @return string
- */
- function urlencode ( $s )
- {
- if ($s === false)
- {
- return $s;
- }
- else
- {
- return str_replace('%7E', '~', rawurlencode($s));
- }
- }
-
- /**
- * Decode a string according to RFC3986.
- * Also correctly decodes RFC1738 urls.
- *
- * @param string s
- * @return string
- */
- function urldecode ( $s )
- {
- if ($s === false)
- {
- return $s;
- }
- else
- {
- return rawurldecode($s);
- }
- }
-
- /**
- * urltranscode - make sure that a value is encoded using RFC3986.
- * We use a basic urldecode() function so that any use of '+' as the
- * encoding of the space character is correctly handled.
- *
- * @param string s
- * @return string
- */
- function urltranscode ( $s )
- {
- if ($s === false)
- {
- return $s;
- }
- else
- {
- return $this->urlencode(urldecode($s));
- }
- }
-
-
- /**
- * Parse the oauth parameters from the request headers
- * Looks for something like:
- *
- * Authorization: OAuth realm="http://photos.example.net/authorize",
- * oauth_consumer_key="dpf43f3p2l4k3l03",
- * oauth_token="nnch734d00sl2jdk",
- * oauth_signature_method="HMAC-SHA1",
- * oauth_signature="tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D",
- * oauth_timestamp="1191242096",
- * oauth_nonce="kllo9940pd9333jh",
- * oauth_version="1.0"
- */
- private function parseHeaders ()
- {
-/*
- $this->headers['Authorization'] = 'OAuth realm="http://photos.example.net/authorize",
- oauth_consumer_key="dpf43f3p2l4k3l03",
- oauth_token="nnch734d00sl2jdk",
- oauth_signature_method="HMAC-SHA1",
- oauth_signature="tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D",
- oauth_timestamp="1191242096",
- oauth_nonce="kllo9940pd9333jh",
- oauth_version="1.0"';
-*/
- if (isset($this->headers['Authorization']))
- {
- $auth = trim($this->headers['Authorization']);
- if (strncasecmp($auth, 'OAuth', 4) == 0)
- {
- $vs = explode(',', substr($auth, 6));
- foreach ($vs as $v)
- {
- if (strpos($v, '='))
- {
- $v = trim($v);
- list($name,$value) = explode('=', $v, 2);
- if (!empty($value) && $value{0} == '"' && substr($value, -1) == '"')
- {
- $value = substr(substr($value, 1), 0, -1);
- }
-
- if (strcasecmp($name, 'realm') == 0)
- {
- $this->realm = $value;
- }
- else
- {
- $this->param[$name] = $value;
- }
- }
- }
- }
- }
- }
-
-
- /**
- * Fetch the content type of the current request
- *
- * @return string
- */
- private function getRequestContentType ()
- {
- $content_type = 'application/octet-stream';
- if (!empty($_SERVER) && array_key_exists('CONTENT_TYPE', $_SERVER))
- {
- list($content_type) = explode(';', $_SERVER['CONTENT_TYPE']);
- }
- return trim($content_type);
- }
-
-
- /**
- * Get the body of a POST or PUT.
- *
- * Used for fetching the post parameters and to calculate the body signature.
- *
- * @return string null when no body present (or wrong content type for body)
- */
- private function getRequestBody ()
- {
- $body = null;
- if ($this->method == 'POST' || $this->method == 'PUT')
- {
- $body = '';
- $fh = @fopen('php://input', 'r');
- if ($fh)
- {
- while (!feof($fh))
- {
- $s = fread($fh, 1024);
- if (is_string($s))
- {
- $body .= $s;
- }
- }
- fclose($fh);
- }
- }
- return $body;
- }
-
-
- /**
- * Simple function to perform a redirect (GET).
- * Redirects the User-Agent, does not return.
- *
- * @param string uri
- * @param array params parameters, urlencoded
- * @exception OAuthException when redirect uri is illegal
- */
- public function redirect ( $uri, $params )
- {
- if (!empty($params))
- {
- $q = array();
- foreach ($params as $name=>$value)
- {
- $q[] = $name.'='.$value;
- }
- $q_s = implode('&', $q);
-
- if (strpos($uri, '?'))
- {
- $uri .= '&'.$q_s;
- }
- else
- {
- $uri .= '?'.$q_s;
- }
- }
-
- // simple security - multiline location headers can inject all kinds of extras
- $uri = preg_replace('/\s/', '%20', $uri);
- if (strncasecmp($uri, 'http://', 7) && strncasecmp($uri, 'https://', 8))
- {
- if (strpos($uri, '://'))
- {
- throw new OAuthException('Illegal protocol in redirect uri '.$uri);
- }
- $uri = 'http://'.$uri;
- }
-
- header('HTTP/1.1 302 Found');
- header('Location: '.$uri);
- echo '';
- exit();
- }
-
-}
-
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/OAuthRequestLogger.php b/mod/oauth_api/vendors/oauth/library/OAuthRequestLogger.php
deleted file mode 100644
index 934c1c53c..000000000
--- a/mod/oauth_api/vendors/oauth/library/OAuthRequestLogger.php
+++ /dev/null
@@ -1,274 +0,0 @@
-<?php
-
-/**
- * Log OAuth requests
- *
- * @version $Id: OAuthRequestLogger.php 55 2009-01-14 15:27:36Z scherpenisse $
- * @author Marc Worrell <marcw@pobox.com>
- * @date Dec 7, 2007 12:22:43 PM
- *
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-class OAuthRequestLogger
-{
- static private $logging = 0;
- static private $enable_logging = null;
- static private $store_log = null;
- static private $note = '';
- static private $user_id = null;
- static private $request_object = null;
- static private $sent = null;
- static private $received = null;
- static private $log = array();
-
- /**
- * Start any logging, checks the system configuration if logging is needed.
- *
- * @param OAuthRequest $request_object
- */
- static function start ( $request_object = null )
- {
- if (defined('OAUTH_LOG_REQUEST'))
- {
- if (is_null(OAuthRequestLogger::$enable_logging))
- {
- OAuthRequestLogger::$enable_logging = true;
- }
- if (is_null(OAuthRequestLogger::$store_log))
- {
- OAuthRequestLogger::$store_log = true;
- }
- }
-
- if (OAuthRequestLogger::$enable_logging && !OAuthRequestLogger::$logging)
- {
- OAuthRequestLogger::$logging = true;
- OAuthRequestLogger::$request_object = $request_object;
- ob_start();
-
- // Make sure we flush our log entry when we stop the request (eg on an exception)
- register_shutdown_function(array('OAuthRequestLogger','flush'));
- }
- }
-
-
- /**
- * Force logging, needed for performing test connects independent from the debugging setting.
- *
- * @param boolean store_log (optional) true to store the log in the db
- */
- static function enableLogging ( $store_log = null )
- {
- OAuthRequestLogger::$enable_logging = true;
- if (!is_null($store_log))
- {
- OAuthRequestLogger::$store_log = $store_log;
- }
- }
-
-
- /**
- * Logs the request to the database, sends any cached output.
- * Also called on shutdown, to make sure we always log the request being handled.
- */
- static function flush ()
- {
- if (OAuthRequestLogger::$logging)
- {
- OAuthRequestLogger::$logging = false;
-
- if (is_null(OAuthRequestLogger::$sent))
- {
- // What has been sent to the user-agent?
- $data = ob_get_contents();
- if (strlen($data) > 0)
- {
- ob_end_flush();
- }
- elseif (ob_get_level())
- {
- ob_end_clean();
- }
- $hs = headers_list();
- $sent = implode("\n", $hs) . "\n\n" . $data;
- }
- else
- {
- // The request we sent
- $sent = OAuthRequestLogger::$sent;
- }
-
- if (is_null(OAuthRequestLogger::$received))
- {
- // Build the request we received
- $hs0 = getallheaders();
- $hs = array();
- foreach ($hs0 as $h => $v)
- {
- $hs[] = "$h: $v";
- }
-
- $data = '';
- $fh = @fopen('php://input', 'r');
- if ($fh)
- {
- while (!feof($fh))
- {
- $s = fread($fh, 1024);
- if (is_string($s))
- {
- $data .= $s;
- }
- }
- fclose($fh);
- }
- $received = implode("\n", $hs) . "\n\n" . $data;
- }
- else
- {
- // The answer we received
- $received = OAuthRequestLogger::$received;
- }
-
- // The request base string
- if (OAuthRequestLogger::$request_object)
- {
- $base_string = OAuthRequestLogger::$request_object->signatureBaseString();
- }
- else
- {
- $base_string = '';
- }
-
- // Figure out to what keys we want to log this request
- $keys = array();
- if (OAuthRequestLogger::$request_object)
- {
- $consumer_key = OAuthRequestLogger::$request_object->getParam('oauth_consumer_key', true);
- $token = OAuthRequestLogger::$request_object->getParam('oauth_token', true);
-
- switch (get_class(OAuthRequestLogger::$request_object))
- {
- // tokens are access/request tokens by a consumer
- case 'OAuthServer':
- case 'OAuthRequestVerifier':
- $keys['ocr_consumer_key'] = $consumer_key;
- $keys['oct_token'] = $token;
- break;
-
- // tokens are access/request tokens to a server
- case 'OAuthRequester':
- case 'OAuthRequestSigner':
- $keys['osr_consumer_key'] = $consumer_key;
- $keys['ost_token'] = $token;
- break;
- }
- }
-
- // Log the request
- if (OAuthRequestLogger::$store_log)
- {
- $store = OAuthStore::instance();
- $store->addLog($keys, $received, $sent, $base_string, OAuthRequestLogger::$note, OAuthRequestLogger::$user_id);
- }
-
- OAuthRequestLogger::$log[] = array(
- 'keys' => $keys,
- 'received' => $received,
- 'sent' => $sent,
- 'base_string' => $base_string,
- 'note' => OAuthRequestLogger::$note
- );
- }
- }
-
-
- /**
- * Add a note, used by the OAuthException to log all exceptions.
- *
- * @param string note
- */
- static function addNote ( $note )
- {
- OAuthRequestLogger::$note .= $note . "\n\n";
- }
-
- /**
- * Set the OAuth request object being used
- *
- * @param OAuthRequest request_object
- */
- static function setRequestObject ( $request_object )
- {
- OAuthRequestLogger::$request_object = $request_object;
- }
-
-
- /**
- * Set the relevant user (defaults to the current user)
- *
- * @param int user_id
- */
- static function setUser ( $user_id )
- {
- OAuthRequestLogger::$user_id = $user_id;
- }
-
-
- /**
- * Set the request we sent
- *
- * @param string request
- */
- static function setSent ( $request )
- {
- OAuthRequestLogger::$sent = $request;
- }
-
- /**
- * Set the reply we received
- *
- * @param string request
- */
- static function setReceived ( $reply )
- {
- OAuthRequestLogger::$received = $reply;
- }
-
-
- /**
- * Get the the log till now
- *
- * @return array
- */
- static function getLog ()
- {
- return OAuthRequestLogger::$log;
- }
-}
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/OAuthRequestSigner.php b/mod/oauth_api/vendors/oauth/library/OAuthRequestSigner.php
deleted file mode 100644
index 9f83f287f..000000000
--- a/mod/oauth_api/vendors/oauth/library/OAuthRequestSigner.php
+++ /dev/null
@@ -1,209 +0,0 @@
-<?php
-
-/**
- * Sign requests before performing the request.
- *
- * @version $Id: OAuthRequestSigner.php 58 2009-02-23 01:47:23Z marcw@pobox.com $
- * @author Marc Worrell <marcw@pobox.com>
- * @date Nov 16, 2007 4:02:49 PM
- *
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-
-require_once dirname(__FILE__) . '/OAuthStore.php';
-require_once dirname(__FILE__) . '/OAuthRequest.php';
-
-
-class OAuthRequestSigner extends OAuthRequest
-{
- protected $request;
- protected $store;
- protected $usr_id = 0;
- private $signed = false;
-
-
- /**
- * Construct the request to be signed. Parses or appends the parameters in the params url.
- * When you supply an params array, then the params should not be urlencoded.
- * When you supply a string, then it is assumed it is of the type application/x-www-form-urlencoded
- *
- * @param string request url
- * @param string method PUT, GET, POST etc.
- * @param mixed params string (for urlencoded data, or array with name/value pairs)
- * @param string body optional body for PUT and/or POST requests
- */
- function __construct ( $request, $method = 'GET', $params = null, $body = null )
- {
- $this->store = OAuthStore::instance();
-
- if (is_string($params))
- {
- parent::__construct($request, $method, $params);
- }
- else
- {
- parent::__construct($request, $method);
- if (is_array($params))
- {
- foreach ($params as $name => $value)
- {
- $this->setParam($name, $value);
- }
- }
- }
-
- // With put/ post we might have a body (not for application/x-www-form-urlencoded requests)
- if ($method == 'PUT' || $method == 'POST')
- {
- $this->setBody($body);
- }
- }
-
-
- /**
- * Reset the 'signed' flag, so that any changes in the parameters force a recalculation
- * of the signature.
- */
- function setUnsigned ()
- {
- $this->signed = false;
- }
-
-
- /**
- * Sign our message in the way the server understands.
- * Set the needed oauth_xxxx parameters.
- *
- * @param int usr_id (optional) user that wants to sign this request
- * @param array secrets secrets used for signing, when empty then secrets will be fetched from the token registry
- * @param string name name of the token to be used for signing
- * @exception OAuthException when there is no oauth relation with the server
- * @exception OAuthException when we don't support the signing methods of the server
- */
- function sign ( $usr_id = 0, $secrets = null, $name = '' )
- {
- $url = $this->getRequestUrl();
- if (empty($secrets))
- {
- // get the access tokens for the site (on an user by user basis)
- $secrets = $this->store->getSecretsForSignature($url, $usr_id, $name);
- }
- if (empty($secrets))
- {
- throw new OAuthException('No OAuth relation with the server for at "'.$url.'"');
- }
-
- $signature_method = $this->selectSignatureMethod($secrets['signature_methods']);
-
- $token = isset($secrets['token']) ? $secrets['token'] : '';
- $token_secret = isset($secrets['token_secret']) ? $secrets['token_secret'] : '';
-
- $this->setParam('oauth_signature_method',$signature_method);
- $this->setParam('oauth_signature', '');
- $this->setParam('oauth_nonce', !empty($secrets['nonce']) ? $secrets['nonce'] : uniqid(''));
- $this->setParam('oauth_timestamp', !empty($secrets['timestamp']) ? $secrets['timestamp'] : time());
- $this->setParam('oauth_token', $token);
- $this->setParam('oauth_consumer_key', $secrets['consumer_key']);
- $this->setParam('oauth_version', '1.0');
-
- $body = $this->getBody();
- if (!is_null($body))
- {
- // We also need to sign the body, use the default signature method
- $body_signature = $this->calculateDataSignature($body, $secrets['consumer_secret'], $token_secret, $signature_method);
- $this->setParam('xoauth_body_signature', $body_signature, true);
- }
-
- $signature = $this->calculateSignature($secrets['consumer_secret'], $token_secret);
- $this->setParam('oauth_signature', $signature, true);
-
- $this->signed = true;
- $this->usr_id = $usr_id;
- }
-
-
- /**
- * Builds the Authorization header for the request.
- * Adds all oauth_ and xoauth_ parameters to the Authorization header.
- *
- * @return string
- */
- function getAuthorizationHeader ()
- {
- if (!$this->signed)
- {
- $this->sign($this->usr_id);
- }
- $h = array();
- $h[] = 'Authorization: OAuth realm=""';
- foreach ($this->param as $name => $value)
- {
- if (strncmp($name, 'oauth_', 6) == 0 || strncmp($name, 'xoauth_', 7) == 0)
- {
- $h[] = $name.'="'.$value.'"';
- }
- }
- $hs = implode(', ', $h);
- return $hs;
- }
-
-
- /**
- * Builds the application/x-www-form-urlencoded parameter string. Can be appended as
- * the query part to a GET or inside the request body for a POST.
- *
- * @param boolean oauth_as_header (optional) set to false to include oauth parameters
- * @return string
- */
- function getQueryString ( $oauth_as_header = true )
- {
- $parms = array();
- foreach ($this->param as $name => $value)
- {
- if ( !$oauth_as_header
- || (strncmp($name, 'oauth_', 6) != 0 && strncmp($name, 'xoauth_', 7) != 0))
- {
- if (is_array($value))
- {
- foreach ($value as $v)
- {
- $parms[] = $name.'='.$v;
- }
- }
- else
- {
- $parms[] = $name.'='.$value;
- }
- }
- }
- return implode('&', $parms);
- }
-
-}
-
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/OAuthRequestVerifier.php b/mod/oauth_api/vendors/oauth/library/OAuthRequestVerifier.php
deleted file mode 100644
index 4b4db9685..000000000
--- a/mod/oauth_api/vendors/oauth/library/OAuthRequestVerifier.php
+++ /dev/null
@@ -1,262 +0,0 @@
-<?php
-
-/**
- * Verify the current request. Checks if signed and if the signature is correct.
- * When correct then also figures out on behalf of which user this request is being made.
- *
- * @version $Id: OAuthRequestVerifier.php 51 2008-10-15 15:15:47Z marcw@pobox.com $
- * @author Marc Worrell <marcw@pobox.com>
- * @date Nov 16, 2007 4:35:03 PM
- *
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require_once dirname(__FILE__) . '/OAuthStore.php';
-require_once dirname(__FILE__) . '/OAuthRequest.php';
-
-
-class OAuthRequestVerifier extends OAuthRequest
-{
- private $request;
- private $store;
-
- /**
- * Construct the request to be verified
- *
- * @param string request
- * @param string method
- */
- function __construct ( $uri = null, $method = 'GET' )
- {
- $this->store = OAuthStore::instance();
- parent::__construct($uri, $method);
-
- OAuthRequestLogger::start($this);
- }
-
-
- /**
- * See if the current request is signed with OAuth
- *
- * @return boolean
- */
- static public function requestIsSigned ()
- {
- if (isset($_REQUEST['oauth_signature']))
- {
- $signed = true;
- }
- else
- {
- $hs = getallheaders();
- if (isset($hs['Authorization']) && strpos($hs['Authorization'], 'oauth_signature') !== false)
- {
- $signed = true;
- }
- else
- {
- $signed = false;
- }
- }
- return $signed;
- }
-
-
- /**
- * Verify the request if it seemed to be signed.
- *
- * @param string token_type the kind of token needed, defaults to 'access'
- * @exception OAuthException thrown when the request did not verify
- * @return boolean true when signed, false when not signed
- */
- public function verifyIfSigned ( $token_type = 'access' )
- {
- if ($this->getParam('oauth_consumer_key'))
- {
- OAuthRequestLogger::start($this);
- $this->verify($token_type);
- $signed = true;
- OAuthRequestLogger::flush();
- }
- else
- {
- $signed = false;
- }
- return $signed;
- }
-
-
- /**
- * Verify the request
- *
- * @param string token_type the kind of token needed, defaults to 'access' (false, 'access', 'request')
- * @exception OAuthException thrown when the request did not verify
- * @return int user_id associated with token (false when no user associated)
- */
- public function verify ( $token_type = 'access' )
- {
- $consumer_key = $this->getParam('oauth_consumer_key');
- $token = $this->getParam('oauth_token');
- $user_id = false;
-
- if ($consumer_key && ($token_type === false || $token))
- {
- $secrets = $this->store->getSecretsForVerify( $this->urldecode($consumer_key),
- $this->urldecode($token),
- $token_type);
-
- $this->store->checkServerNonce( $this->urldecode($consumer_key),
- $this->urldecode($token),
- $this->getParam('oauth_timestamp', true),
- $this->getParam('oauth_nonce', true));
-
- $oauth_sig = $this->getParam('oauth_signature');
- if (empty($oauth_sig))
- {
- throw new OAuthException('Verification of signature failed (no oauth_signature in request).');
- }
-
- try
- {
- $this->verifySignature($secrets['consumer_secret'], $secrets['token_secret'], $token_type);
- }
- catch (OAuthException $e)
- {
- throw new OAuthException('Verification of signature failed (signature base string was "'.$this->signatureBaseString().'").');
- }
-
- // Check the optional body signature
- if ($this->getParam('xoauth_body_signature'))
- {
- $method = $this->getParam('xoauth_body_signature_method');
- if (empty($method))
- {
- $method = $this->getParam('oauth_signature_method');
- }
-
- try
- {
- $this->verifyDataSignature($this->getBody(), $secrets['consumer_secret'], $secrets['token_secret'], $method, $this->getParam('xoauth_body_signature'));
- }
- catch (OAuthException $e)
- {
- throw new OAuthException('Verification of body signature failed.');
- }
- }
-
- // All ok - fetch the user associated with this request
- if (isset($secrets['user_id']))
- {
- $user_id = $secrets['user_id'];
- }
-
- // Check if the consumer wants us to reset the ttl of this token
- $ttl = $this->getParam('xoauth_token_ttl', true);
- if (is_numeric($ttl))
- {
- $this->store->setConsumerAccessTokenTtl($this->urldecode($token), $ttl);
- }
- }
- else
- {
- throw new OAuthException('Can\'t verify request, missing oauth_consumer_key or oauth_token');
- }
- return $user_id;
- }
-
-
-
- /**
- * Verify the signature of the request, using the method in oauth_signature_method.
- * The signature is returned encoded in the form as used in the url. So the base64 and
- * urlencoding has been done.
- *
- * @param string consumer_secret
- * @param string token_secret
- * @exception OAuthException thrown when the signature method is unknown
- * @exception OAuthException when not all parts available
- * @exception OAuthException when signature does not match
- */
- public function verifySignature ( $consumer_secret, $token_secret, $token_type = 'access' )
- {
- $required = array(
- 'oauth_consumer_key',
- 'oauth_signature_method',
- 'oauth_timestamp',
- 'oauth_nonce',
- 'oauth_signature'
- );
-
- if ($token_type !== false)
- {
- $required[] = 'oauth_token';
- }
-
- foreach ($required as $req)
- {
- if (!isset($this->param[$req]))
- {
- throw new OAuthException('Can\'t verify request signature, missing parameter "'.$req.'"');
- }
- }
-
- $this->checks();
-
- $base = $this->signatureBaseString();
- $this->verifyDataSignature($base, $consumer_secret, $token_secret, $this->param['oauth_signature_method'], $this->param['oauth_signature']);
- }
-
-
-
- /**
- * Verify the signature of a string.
- *
- * @param string data
- * @param string consumer_secret
- * @param string token_secret
- * @param string signature_method
- * @param string signature
- * @exception OAuthException thrown when the signature method is unknown
- * @exception OAuthException when signature does not match
- */
- public function verifyDataSignature ( $data, $consumer_secret, $token_secret, $signature_method, $signature )
- {
- if (is_null($data))
- {
- $data = '';
- }
-
- $sig = $this->getSignatureMethod($signature_method);
- if (!$sig->verify($this, $data, $consumer_secret, $token_secret, $signature))
- {
- throw new OAuthException('Signature verification failed ('.$signature_method.')');
- }
- }
-
-}
-
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/OAuthRequester.php b/mod/oauth_api/vendors/oauth/library/OAuthRequester.php
deleted file mode 100644
index 87f9586c0..000000000
--- a/mod/oauth_api/vendors/oauth/library/OAuthRequester.php
+++ /dev/null
@@ -1,508 +0,0 @@
-<?php
-
-/**
- * Perform a signed OAuth request with a GET, POST, PUT or DELETE operation.
- *
- * @version $Id: OAuthRequester.php 63 2009-02-25 10:24:33Z marcw@pobox.com $
- * @author Marc Worrell <marcw@pobox.com>
- * @date Nov 20, 2007 1:41:38 PM
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require_once dirname(__FILE__) . '/OAuthRequestSigner.php';
-require_once dirname(__FILE__) . '/body/OAuthBodyContentDisposition.php';
-
-
-class OAuthRequester extends OAuthRequestSigner
-{
- protected $files;
-
- /**
- * Construct a new request signer. Perform the request with the doRequest() method below.
- *
- * A request can have either one file or a body, not both.
- *
- * The files array consists of arrays:
- * - file the filename/path containing the data for the POST/PUT
- * - data data for the file, omit when you have a file
- * - mime content-type of the file
- * - filename filename for content disposition header
- *
- * When OAuth (and PHP) can support multipart/form-data then we can handle more than one file.
- * For now max one file, with all the params encoded in the query string.
- *
- * @param string request
- * @param string method http method. GET, PUT, POST etc.
- * @param array params name=>value array with request parameters
- * @param string body optional body to send
- * @param array files optional files to send (max 1 till OAuth support multipart/form-data posts)
- */
- function __construct ( $request, $method = 'GET', $params = null, $body = null, $files = null )
- {
- parent::__construct($request, $method, $params, $body);
-
- // When there are files, then we can construct a POST with a single file
- if (!empty($files))
- {
- $empty = true;
- foreach ($files as $f)
- {
- $empty = $empty && empty($f['file']) && !isset($f['data']);
- }
-
- if (!$empty)
- {
- if (!is_null($body))
- {
- throw new OAuthException('When sending files, you can\'t send a body as well.');
- }
- $this->files = $files;
- }
- }
- }
-
-
- /**
- * Perform the request, returns the response code, headers and body.
- *
- * @param int usr_id optional user id for which we make the request
- * @param array curl_options optional extra options for curl request
- * @param array options options like name and token_ttl
- * @exception OAuthException when authentication not accepted
- * @exception OAuthException when signing was not possible
- * @return array (code=>int, headers=>array(), body=>string)
- */
- function doRequest ( $usr_id = 0, $curl_options = array(), $options = array() )
- {
- $name = isset($options['name']) ? $options['name'] : '';
- if (isset($options['token_ttl']))
- {
- $this->setParam('xoauth_token_ttl', intval($options['token_ttl']));
- }
-
- if (!empty($this->files))
- {
- // At the moment OAuth does not support multipart/form-data, so try to encode
- // the supplied file (or data) as the request body and add a content-disposition header.
- list($extra_headers, $body) = OAuthBodyContentDisposition::encodeBody($this->files);
- $this->setBody($body);
- $curl_options = $this->prepareCurlOptions($curl_options, $extra_headers);
- }
- $this->sign($usr_id, null, $name);
- $text = $this->curl_raw($curl_options);
- $result = $this->curl_parse($text);
- if ($result['code'] >= 400)
- {
- throw new OAuthException('Request failed with code ' . $result['code'] . ': ' . $result['body']);
- }
-
- // Record the token time to live for this server access token, immediate delete iff ttl <= 0
- // Only done on a succesful request.
- $token_ttl = $this->getParam('xoauth_token_ttl', false);
- if (is_numeric($token_ttl))
- {
- $this->store->setServerTokenTtl($this->getParam('oauth_consumer_key',true), $this->getParam('oauth_token',true), $token_ttl);
- }
-
- return $result;
- }
-
-
- /**
- * Request a request token from the site belonging to consumer_key
- *
- * @param string consumer_key
- * @param int usr_id
- * @param array params (optional) extra arguments for when requesting the request token
- * @param string method (optional) change the method of the request, defaults to POST (as it should be)
- * @param array options (optional) options like name and token_ttl
- * @exception OAuthException when no key could be fetched
- * @exception OAuthException when no server with consumer_key registered
- * @return array (authorize_uri, token)
- */
- static function requestRequestToken ( $consumer_key, $usr_id, $params = null, $method = 'POST', $options = array() )
- {
- OAuthRequestLogger::start();
-
- if (isset($options['token_ttl']) && is_numeric($options['token_ttl']))
- {
- $params['xoauth_token_ttl'] = intval($options['token_ttl']);
- }
-
- $store = OAuthStore::instance();
- $r = $store->getServer($consumer_key, $usr_id);
- $uri = $r['request_token_uri'];
-
- $oauth = new OAuthRequester($uri, $method, $params);
- $oauth->sign($usr_id, $r);
- $text = $oauth->curl_raw();
-
- if (empty($text))
- {
- throw new OAuthException('No answer from the server "'.$uri.'" while requesting a request token');
- }
- $data = $oauth->curl_parse($text);
- if ($data['code'] != 200)
- {
- throw new OAuthException('Unexpected result from the server "'.$uri.'" ('.$data['code'].') while requesting a request token');
- }
- $token = array();
- $params = explode('&', $data['body']);
- foreach ($params as $p)
- {
- @list($name, $value) = explode('=', $p, 2);
- $token[$name] = $oauth->urldecode($value);
- }
-
- if (!empty($token['oauth_token']) && !empty($token['oauth_token_secret']))
- {
- $opts = array();
- if (isset($options['name']))
- {
- $opts['name'] = $options['name'];
- }
- if (isset($token['xoauth_token_ttl']))
- {
- $opts['token_ttl'] = $token['xoauth_token_ttl'];
- }
- $store->addServerToken($consumer_key, 'request', $token['oauth_token'], $token['oauth_token_secret'], $usr_id, $opts);
- }
- else
- {
- throw new OAuthException('The server "'.$uri.'" did not return the oauth_token or the oauth_token_secret');
- }
-
- OAuthRequestLogger::flush();
-
- // Now we can direct a browser to the authorize_uri
- return array(
- 'authorize_uri' => $r['authorize_uri'],
- 'token' => $token['oauth_token']
- );
- }
-
-
- /**
- * Request an access token from the site belonging to consumer_key.
- * Before this we got an request token, now we want to exchange it for
- * an access token.
- *
- * @param string consumer_key
- * @param string token
- * @param int usr_id user requesting the access token
- * @param string method (optional) change the method of the request, defaults to POST (as it should be)
- * @param array options (optional) extra options for request, eg token_ttl
- * @exception OAuthException when no key could be fetched
- * @exception OAuthException when no server with consumer_key registered
- */
- static function requestAccessToken ( $consumer_key, $token, $usr_id, $method = 'POST', $options = array() )
- {
- OAuthRequestLogger::start();
-
- $store = OAuthStore::instance();
- $r = $store->getServerTokenSecrets($consumer_key, $token, 'request', $usr_id);
- $uri = $r['access_token_uri'];
- $token_name = $r['token_name'];
-
- // Delete the server request token, this one was for one use only
- $store->deleteServerToken($consumer_key, $r['token'], 0, true);
-
- // Try to exchange our request token for an access token
- $oauth = new OAuthRequester($uri, $method);
-
- if (isset($options['token_ttl']) && is_numeric($options['token_ttl']))
- {
- $oauth->setParam('xoauth_token_ttl', intval($options['token_ttl']));
- }
-
- OAuthRequestLogger::setRequestObject($oauth);
-
- $oauth->sign($usr_id, $r);
- $text = $oauth->curl_raw();
- if (empty($text))
- {
- throw new OAuthException('No answer from the server "'.$uri.'" while requesting a request token');
- }
- $data = $oauth->curl_parse($text);
-
- if ($data['code'] != 200)
- {
- throw new OAuthException('Unexpected result from the server "'.$uri.'" ('.$data['code'].') while requesting a request token');
- }
-
- $token = array();
- $params = explode('&', $data['body']);
- foreach ($params as $p)
- {
- @list($name, $value) = explode('=', $p, 2);
- $token[$oauth->urldecode($name)] = $oauth->urldecode($value);
- }
-
- if (!empty($token['oauth_token']) && !empty($token['oauth_token_secret']))
- {
- $opts = array();
- $opts['name'] = $token_name;
- if (isset($token['xoauth_token_ttl']))
- {
- $opts['token_ttl'] = $token['xoauth_token_ttl'];
- }
- $store->addServerToken($consumer_key, 'access', $token['oauth_token'], $token['oauth_token_secret'], $usr_id, $opts);
- }
- else
- {
- throw new OAuthException('The server "'.$uri.'" did not return the oauth_token or the oauth_token_secret');
- }
-
- OAuthRequestLogger::flush();
- }
-
-
-
- /**
- * Open and close a curl session passing all the options to the curl libs
- *
- * @param string url the http address to fetch
- * @exception OAuthException when temporary file for PUT operation could not be created
- * @return string the result of the curl action
- */
- protected function curl_raw ( $opts = array() )
- {
- if (isset($opts[CURLOPT_HTTPHEADER]))
- {
- $header = $opts[CURLOPT_HTTPHEADER];
- }
- else
- {
- $header = array();
- }
-
- $ch = curl_init();
- $method = $this->getMethod();
- $url = $this->getRequestUrl();
- $header[] = $this->getAuthorizationHeader();
- $query = $this->getQueryString();
- $body = $this->getBody();
-
- $has_content_type = false;
- foreach ($header as $h)
- {
- if (strncasecmp($h, 'Content-Type:', 13) == 0)
- {
- $has_content_type = true;
- }
- }
-
- if (!is_null($body))
- {
- if ($method == 'TRACE')
- {
- throw new OAuthException('A body can not be sent with a TRACE operation');
- }
-
- // PUT and POST allow a request body
- if (!empty($query))
- {
- $url .= '?'.$query;
- }
-
- // Make sure that the content type of the request is ok
- if (!$has_content_type)
- {
- $header[] = 'Content-Type: application/octet-stream';
- $has_content_type = true;
- }
-
- // When PUTting, we need to use an intermediate file (because of the curl implementation)
- if ($method == 'PUT')
- {
- /*
- if (version_compare(phpversion(), '5.2.0') >= 0)
- {
- // Use the data wrapper to create the file expected by the put method
- $put_file = fopen('data://application/octet-stream;base64,'.base64_encode($body));
- }
- */
-
- $put_file = @tmpfile();
- if (!$put_file)
- {
- throw new OAuthException('Could not create tmpfile for PUT operation');
- }
- fwrite($put_file, $body);
- fseek($put_file, 0);
-
- curl_setopt($ch, CURLOPT_PUT, true);
- curl_setopt($ch, CURLOPT_INFILE, $put_file);
- curl_setopt($ch, CURLOPT_INFILESIZE, strlen($body));
- }
- else
- {
- curl_setopt($ch, CURLOPT_POST, true);
- curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
- }
- }
- else
- {
- // a 'normal' request, no body to be send
- if ($method == 'POST')
- {
- if (!$has_content_type)
- {
- $header[] = 'Content-Type: application/x-www-form-urlencoded';
- $has_content_type = true;
- }
-
- curl_setopt($ch, CURLOPT_POST, true);
- curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
- }
- else
- {
- if (!empty($query))
- {
- $url .= '?'.$query;
- }
- if ($method != 'GET')
- {
- curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
- }
- }
- }
-
- curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
- curl_setopt($ch, CURLOPT_USERAGENT, 'anyMeta/OAuth 1.0 - ($LastChangedRevision: 63 $)');
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_HEADER, true);
-
- foreach ($opts as $k => $v)
- {
- if ($k != CURLOPT_HTTPHEADER)
- {
- curl_setopt($ch, $k, $v);
- }
- }
-
- $txt = curl_exec($ch);
- curl_close($ch);
-
- if (!empty($put_file))
- {
- fclose($put_file);
- }
-
- // Tell the logger what we requested and what we received back
- $data = $method . " $url\n".implode("\n",$header);
- if (is_string($body))
- {
- $data .= "\n\n".$body;
- }
- else if ($method == 'POST')
- {
- $data .= "\n\n".$query;
- }
-
- OAuthRequestLogger::setSent($data, $body);
- OAuthRequestLogger::setReceived($txt);
-
- return $txt;
- }
-
-
- /**
- * Parse an http response
- *
- * @param string response the http text to parse
- * @return array (code=>http-code, headers=>http-headers, body=>body)
- */
- protected function curl_parse ( $response )
- {
- if (empty($response))
- {
- return array();
- }
-
- @list($headers,$body) = explode("\r\n\r\n",$response,2);
- $lines = explode("\r\n",$headers);
-
- if (preg_match('@^HTTP/[0-9]\.[0-9] +100@', $lines[0]))
- {
- /* HTTP/1.x 100 Continue
- * the real data is on the next line
- */
- @list($headers,$body) = explode("\r\n\r\n",$body,2);
- $lines = explode("\r\n",$headers);
- }
-
- // first line of headers is the HTTP response code
- $http_line = array_shift($lines);
- if (preg_match('@^HTTP/[0-9]\.[0-9] +([0-9]{3})@', $http_line, $matches))
- {
- $code = $matches[1];
- }
-
- // put the rest of the headers in an array
- $headers = array();
- foreach ($lines as $l)
- {
- list($k, $v) = explode(': ', $l, 2);
- $headers[strtolower($k)] = $v;
- }
-
- return array( 'code' => $code, 'headers' => $headers, 'body' => $body);
- }
-
-
- /**
- * Mix the given headers into the headers that were given to curl
- *
- * @param array curl_options
- * @param array extra_headers
- * @return array new curl options
- */
- protected function prepareCurlOptions ( $curl_options, $extra_headers )
- {
- $hs = array();
- if (!empty($curl_options[CURLOPT_HTTPHEADER]) && is_array($curl_options[CURLOPT_HTTPHEADER]))
- {
- foreach ($curl_options[CURLOPT_HTTPHEADER] as $h)
- {
- list($opt, $val) = explode(':', $h, 2);
- $opt = str_replace(' ', '-', ucwords(str_replace('-', ' ', $opt)));
- $hs[$opt] = $val;
- }
- }
-
- $curl_options[CURLOPT_HTTPHEADER] = array();
- $hs = array_merge($hs, $extra_headers);
- foreach ($hs as $h => $v)
- {
- $curl_options[CURLOPT_HTTPHEADER][] = "$h: $v";
- }
- return $curl_options;
- }
-}
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/OAuthServer.php b/mod/oauth_api/vendors/oauth/library/OAuthServer.php
deleted file mode 100644
index c7f9097b3..000000000
--- a/mod/oauth_api/vendors/oauth/library/OAuthServer.php
+++ /dev/null
@@ -1,232 +0,0 @@
-<?php
-
-/**
- * Server layer over the OAuthRequest handler
- *
- * @version $Id: OAuthServer.php 51 2008-10-15 15:15:47Z marcw@pobox.com $
- * @author Marc Worrell <marcw@pobox.com>
- * @date Nov 27, 2007 12:36:38 PM
- *
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require_once 'OAuthRequestVerifier.php';
-
-class OAuthServer extends OAuthRequestVerifier
-{
- /**
- * Handle the request_token request.
- * Returns the new request token and request token secret.
- *
- * TODO: add correct result code to exception
- *
- * @return string returned request token, false on an error
- */
- public function requestToken ()
- {
- OAuthRequestLogger::start($this);
- try
- {
- $this->verify(false);
-
- $options = array();
- $ttl = $this->getParam('xoauth_token_ttl', false);
- if ($ttl)
- {
- $options['token_ttl'] = $ttl;
- }
-
- // Create a request token
- $store = OAuthStore::instance();
- $token = $store->addConsumerRequestToken($this->getParam('oauth_consumer_key', true), $options);
- $result = 'oauth_token='.$this->urlencode($token['token'])
- .'&oauth_token_secret='.$this->urlencode($token['token_secret']);
-
- if (!empty($token['token_ttl']))
- {
- $result .= '&xoauth_token_ttl='.$this->urlencode($token['token_ttl']);
- }
-
- $request_token = $token['token'];
-
- header('HTTP/1.1 200 OK');
- header('Content-Length: '.strlen($result));
- header('Content-Type: application/x-www-form-urlencoded');
-
- echo $result;
- }
- catch (OAuthException $e)
- {
- $request_token = false;
-
- header('HTTP/1.1 401 Unauthorized');
- header('Content-Type: text/plain');
-
- echo "OAuth Verification Failed: " . $e->getMessage();
- }
-
- OAuthRequestLogger::flush();
- return $request_token;
- }
-
-
- /**
- * Verify the start of an authorization request. Verifies if the request token is valid.
- * Next step is the method authorizeFinish()
- *
- * Nota bene: this stores the current token, consumer key and callback in the _SESSION
- *
- * @exception OAuthException thrown when not a valid request
- * @return array token description
- */
- public function authorizeVerify ( )
- {
- OAuthRequestLogger::start($this);
-
- $store = OAuthStore::instance();
- $token = $this->getParam('oauth_token', true);
- $rs = $store->getConsumerRequestToken($token);
- if (empty($rs))
- {
- throw new OAuthException('Unknown request token "'.$token.'"');
- }
-
- // We need to remember the callback
- if ( empty($_SESSION['verify_oauth_token'])
- || strcmp($_SESSION['verify_oauth_token'], $rs['token']))
- {
- $_SESSION['verify_oauth_token'] = $rs['token'];
- $_SESSION['verify_oauth_consumer_key'] = $rs['consumer_key'];
- $_SESSION['verify_oauth_callback'] = $this->getParam('oauth_callback', true);
- }
- OAuthRequestLogger::flush();
- return $rs;
- }
-
-
- /**
- * Overrule this method when you want to display a nice page when
- * the authorization is finished. This function does not know if the authorization was
- * succesfull, you need to check the token in the database.
- *
- * @param boolean authorized if the current token (oauth_token param) is authorized or not
- * @param int user_id user for which the token was authorized (or denied)
- */
- public function authorizeFinish ( $authorized, $user_id )
- {
- OAuthRequestLogger::start($this);
-
- $token = $this->getParam('oauth_token', true);
- if ( isset($_SESSION['verify_oauth_token'])
- && $_SESSION['verify_oauth_token'] == $token)
- {
- // Flag the token as authorized, or remove the token when not authorized
- $store = OAuthStore::instance();
-
- // Fetch the referrer host from the oauth callback parameter
- $referrer_host = '';
- $oauth_callback = false;
- if (!empty($_SESSION['verify_oauth_callback']))
- {
- $oauth_callback = $_SESSION['verify_oauth_callback'];
- $ps = parse_url($oauth_callback);
- if (isset($ps['host']))
- {
- $referrer_host = $ps['host'];
- }
- }
-
- if ($authorized)
- {
- OAuthRequestLogger::addNote('Authorized token "'.$token.'" for user '.$user_id.' with referrer "'.$referrer_host.'"');
- $store->authorizeConsumerRequestToken($token, $user_id, $referrer_host);
- }
- else
- {
- OAuthRequestLogger::addNote('Authorization rejected for token "'.$token.'" for user '.$user_id."\nToken has been deleted");
- $store->deleteConsumerRequestToken($token);
- }
-
- if (!empty($oauth_callback))
- {
- $this->redirect($oauth_callback, array('oauth_token'=>rawurlencode($token)));
- }
- }
- OAuthRequestLogger::flush();
- }
-
-
- /**
- * Exchange a request token for an access token.
- * The exchange is only succesful iff the request token has been authorized.
- *
- * Never returns, calls exit() when token is exchanged or when error is returned.
- */
- public function accessToken ()
- {
- OAuthRequestLogger::start($this);
-
- try
- {
- $this->verify('request');
-
- $options = array();
- $ttl = $this->getParam('xoauth_token_ttl', false);
- if ($ttl)
- {
- $options['token_ttl'] = $ttl;
- }
-
- $store = OAuthStore::instance();
- $token = $store->exchangeConsumerRequestForAccessToken($this->getParam('oauth_token', true), $options);
- $result = 'oauth_token='.$this->urlencode($token['token'])
- .'&oauth_token_secret='.$this->urlencode($token['token_secret']);
-
- if (!empty($token['token_ttl']))
- {
- $result .= '&xoauth_token_ttl='.$this->urlencode($token['token_ttl']);
- }
-
- header('HTTP/1.1 200 OK');
- header('Content-Length: '.strlen($result));
- header('Content-Type: application/x-www-form-urlencoded');
-
- echo $result;
- }
- catch (OAuthException $e)
- {
- header('HTTP/1.1 401 Access Denied');
- header('Content-Type: text/plain');
-
- echo "OAuth Verification Failed: " . $e->getMessage();
- }
-
- OAuthRequestLogger::flush();
- exit();
- }
-}
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/OAuthStore.php b/mod/oauth_api/vendors/oauth/library/OAuthStore.php
deleted file mode 100644
index 1841ab5fa..000000000
--- a/mod/oauth_api/vendors/oauth/library/OAuthStore.php
+++ /dev/null
@@ -1,86 +0,0 @@
-<?php
-
-/**
- * Storage container for the oauth credentials, both server and consumer side.
- * This is the factory to select the store you want to use
- *
- * @version $Id: OAuthStore.php 49 2008-10-01 09:43:19Z marcw@pobox.com $
- * @author Marc Worrell <marcw@pobox.com>
- * @date Nov 16, 2007 4:03:30 PM
- *
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require_once dirname(__FILE__) . '/OAuthException.php';
-
-class OAuthStore
-{
- static private $instance = false;
-
- /**
- * Request an instance of the OAuthStore
- */
- public static function instance ( $store = 'MySQL', $options = array() )
- {
- if (!OAuthStore::$instance)
- {
- // Select the store you want to use
- if (strpos($store, '/') === false)
- {
- $class = 'OAuthStore'.$store;
- $file = dirname(__FILE__) . '/store/'.$class.'.php';
- }
- else
- {
- $file = $store;
- $store = basename($file, '.php');
- $class = $store;
- }
-
- if (is_file($file))
- {
- require_once $file;
-
- if (class_exists($class))
- {
- OAuthStore::$instance = new $class($options);
- }
- else
- {
- throw new OAuthException('Could not find class '.$class.' in file '.$file);
- }
- }
- else
- {
- throw new OAuthException('No OAuthStore for '.$store.' (file '.$file.')');
- }
- }
- return OAuthStore::$instance;
- }
-}
-
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/body/OAuthBodyContentDisposition.php b/mod/oauth_api/vendors/oauth/library/body/OAuthBodyContentDisposition.php
deleted file mode 100644
index 84123b6d0..000000000
--- a/mod/oauth_api/vendors/oauth/library/body/OAuthBodyContentDisposition.php
+++ /dev/null
@@ -1,129 +0,0 @@
-<?php
-
-/**
- * Add the extra headers for a PUT or POST request with a file.
- *
- * @version $Id$
- * @author Marc Worrell <marcw@pobox.com>
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-class OAuthBodyContentDisposition
-{
- /**
- * Builds the request string.
- *
- * The files array can be a combination of the following (either data or file):
- *
- * file => "path/to/file", filename=, mime=, data=
- *
- * @param array files (name => filedesc) (not urlencoded)
- * @return array (headers, body)
- */
- static function encodeBody ( $files )
- {
- $headers = array();
- $body = null;
-
- // 1. Add all the files to the post
- if (!empty($files))
- {
- foreach ($files as $name => $f)
- {
- $data = false;
- $filename = false;
-
- if (isset($f['filename']))
- {
- $filename = $f['filename'];
- }
-
- if (!empty($f['file']))
- {
- $data = @file_get_contents($f['file']);
- if ($data === false)
- {
- throw new OAuthException(sprintf('Could not read the file "%s" for request body', $f['file']));
- }
- if (empty($filename))
- {
- $filename = basename($f['file']);
- }
- }
- else if (isset($f['data']))
- {
- $data = $f['data'];
- }
-
- // When there is data, add it as a request body, otherwise silently skip the upload
- if ($data !== false)
- {
- if (isset($headers['Content-Disposition']))
- {
- throw new OAuthException('Only a single file (or data) allowed in a signed PUT/POST request body.');
- }
-
- if (empty($filename))
- {
- $filename = 'untitled';
- }
- $mime = !empty($f['mime']) ? $f['mime'] : 'application/octet-stream';
-
- $headers['Content-Disposition'] = 'attachment; filename="'.OAuthBodyContentDisposition::encodeParameterName($filename).'"';
- $headers['Content-Type'] = $mime;
-
- $body = $data;
- }
-
- }
-
- // When we have a body, add the content-length
- if (!is_null($body))
- {
- $headers['Content-Length'] = strlen($body);
- }
- }
- return array($headers, $body);
- }
-
-
- /**
- * Encode a parameter's name for use in a multipart header.
- * For now we do a simple filter that removes some unwanted characters.
- * We might want to implement RFC1522 here. See http://tools.ietf.org/html/rfc1522
- *
- * @param string name
- * @return string
- */
- static function encodeParameterName ( $name )
- {
- return preg_replace('/[^\x20-\x7f]|"/', '-', $name);
- }
-}
-
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/body/OAuthBodyMultipartFormdata.php b/mod/oauth_api/vendors/oauth/library/body/OAuthBodyMultipartFormdata.php
deleted file mode 100644
index 048fdeb63..000000000
--- a/mod/oauth_api/vendors/oauth/library/body/OAuthBodyMultipartFormdata.php
+++ /dev/null
@@ -1,143 +0,0 @@
-<?php
-
-/**
- * Create the body for a multipart/form-data message.
- *
- * @version $Id: OAuthMultipartFormdata.php 6 2008-02-13 12:35:09Z marcw@pobox.com $
- * @author Marc Worrell <marcw@pobox.com>
- * @date Jan 31, 2008 12:50:05 PM
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-
-class OAuthBodyMultipartFormdata
-{
- /**
- * Builds the request string.
- *
- * The files array can be a combination of the following (either data or file):
- *
- * file => "path/to/file", filename=, mime=, data=
- *
- * @param array params (name => value) (all names and values should be urlencoded)
- * @param array files (name => filedesc) (not urlencoded)
- * @return array (headers, body)
- */
- static function encodeBody ( $params, $files )
- {
- $headers = array();
- $body = '';
- $boundary = 'OAuthRequester_'.md5(uniqid('multipart') . microtime());
- $headers['Content-Type'] = 'multipart/form-data; boundary=' . $boundary;
-
-
- // 1. Add the parameters to the post
- if (!empty($params))
- {
- foreach ($params as $name => $value)
- {
- $body .= '--'.$boundary."\r\n";
- $body .= 'Content-Disposition: form-data; name="'.OAuthBodyMultipartFormdata::encodeParameterName(rawurldecode($name)).'"';
- $body .= "\r\n\r\n";
- $body .= urldecode($value);
- $body .= "\r\n";
- }
- }
-
- // 2. Add all the files to the post
- if (!empty($files))
- {
- $untitled = 1;
-
- foreach ($files as $name => $f)
- {
- $data = false;
- $filename = false;
-
- if (isset($f['filename']))
- {
- $filename = $f['filename'];
- }
-
- if (!empty($f['file']))
- {
- $data = @file_get_contents($f['file']);
- if ($data === false)
- {
- throw new OAuthException(sprintf('Could not read the file "%s" for form-data part', $f['file']));
- }
- if (empty($filename))
- {
- $filename = basename($f['file']);
- }
- }
- else if (isset($f['data']))
- {
- $data = $f['data'];
- }
-
- // When there is data, add it as a form-data part, otherwise silently skip the upload
- if ($data !== false)
- {
- if (empty($filename))
- {
- $filename = sprintf('untitled-%d', $untitled++);
- }
- $mime = !empty($f['mime']) ? $f['mime'] : 'application/octet-stream';
- $body .= '--'.$boundary."\r\n";
- $body .= 'Content-Disposition: form-data; name="'.OAuthBodyMultipartFormdata::encodeParameterName($name).'"; filename="'.OAuthBodyMultipartFormdata::encodeParameterName($filename).'"'."\r\n";
- $body .= 'Content-Type: '.$mime;
- $body .= "\r\n\r\n";
- $body .= $data;
- $body .= "\r\n";
- }
-
- }
- }
- $body .= '--'.$boundary."--\r\n";
-
- $headers['Content-Length'] = strlen($body);
- return array($headers, $body);
- }
-
-
- /**
- * Encode a parameter's name for use in a multipart header.
- * For now we do a simple filter that removes some unwanted characters.
- * We might want to implement RFC1522 here. See http://tools.ietf.org/html/rfc1522
- *
- * @param string name
- * @return string
- */
- static function encodeParameterName ( $name )
- {
- return preg_replace('/[^\x20-\x7f]|"/', '-', $name);
- }
-}
-
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/discovery/xrds_parse.php b/mod/oauth_api/vendors/oauth/library/discovery/xrds_parse.php
deleted file mode 100644
index c9cf94997..000000000
--- a/mod/oauth_api/vendors/oauth/library/discovery/xrds_parse.php
+++ /dev/null
@@ -1,304 +0,0 @@
-<?php
-
-/**
- * Parse a XRDS discovery description to a simple array format.
- *
- * For now a simple parse of the document. Better error checking
- * in a later version.
- *
- * @version $Id$
- * @author Marc Worrell <marcw@pobox.com>
- *
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* example of use:
-
-header('content-type: text/plain');
-$file = file_get_contents('../../test/discovery/xrds-magnolia.xrds');
-$xrds = xrds_parse($file);
-print_r($xrds);
-
- */
-
-/**
- * Parse the xrds file in the argument. The xrds description must have been
- * fetched via curl or something else.
- *
- * TODO: more robust checking, support for more service documents
- * TODO: support for URIs to definition instead of local xml:id
- *
- * @param string data contents of xrds file
- * @exception Exception when the file is in an unknown format
- * @return array
- */
-function xrds_parse ( $data )
-{
- $oauth = array();
- $doc = @DOMDocument::loadXML($data);
- if ($doc === false)
- {
- throw new Exception('Error in XML, can\'t load XRDS document');
- }
-
- $xpath = new DOMXPath($doc);
- $xpath->registerNamespace('xrds', 'xri://$xrds');
- $xpath->registerNamespace('xrd', 'xri://$XRD*($v*2.0)');
- $xpath->registerNamespace('simple', 'http://xrds-simple.net/core/1.0');
-
- // Yahoo! uses this namespace, with lowercase xrd in it
- $xpath->registerNamespace('xrd2', 'xri://$xrd*($v*2.0)');
-
- $uris = xrds_oauth_service_uris($xpath);
-
- foreach ($uris as $uri)
- {
- // TODO: support uris referring to service documents outside this one
- if ($uri{0} == '#')
- {
- $id = substr($uri, 1);
- $oauth = xrds_xrd_oauth($xpath, $id);
- if (is_array($oauth) && !empty($oauth))
- {
- return $oauth;
- }
- }
- }
-
- return false;
-}
-
-
-/**
- * Parse a XRD definition for OAuth and return the uris etc.
- *
- * @param XPath xpath
- * @param string id
- * @return array
- */
-function xrds_xrd_oauth ( $xpath, $id )
-{
- $oauth = array();
- $xrd = $xpath->query('//xrds:XRDS/xrd:XRD[@xml:id="'.$id.'"]');
- if ($xrd->length == 0)
- {
- // Yahoo! uses another namespace
- $xrd = $xpath->query('//xrds:XRDS/xrd2:XRD[@xml:id="'.$id.'"]');
- }
-
- if ($xrd->length >= 1)
- {
- $x = $xrd->item(0);
- $services = array();
- foreach ($x->childNodes as $n)
- {
- switch ($n->nodeName)
- {
- case 'Type':
- if ($n->nodeValue != 'xri://$xrds*simple')
- {
- // Not a simple XRDS document
- return false;
- }
- break;
- case 'Expires':
- $oauth['expires'] = $n->nodeValue;
- break;
- case 'Service':
- list($type,$service) = xrds_xrd_oauth_service($n);
- if ($type)
- {
- $services[$type][xrds_priority($n)][] = $service;
- }
- break;
- }
- }
-
- // Flatten the services on priority
- foreach ($services as $type => $service)
- {
- $oauth[$type] = xrds_priority_flatten($service);
- }
- }
- else
- {
- $oauth = false;
- }
- return $oauth;
-}
-
-
-/**
- * Parse a service definition for OAuth in a simple xrd element
- *
- * @param DOMElement n
- * @return array (type, service desc)
- */
-function xrds_xrd_oauth_service ( $n )
-{
- $service = array(
- 'uri' => '',
- 'signature_method' => array(),
- 'parameters' => array()
- );
-
- $type = false;
- foreach ($n->childNodes as $c)
- {
- $name = $c->nodeName;
- $value = $c->nodeValue;
-
- if ($name == 'URI')
- {
- $service['uri'] = $value;
- }
- else if ($name == 'Type')
- {
- if (strncmp($value, 'http://oauth.net/core/1.0/endpoint/', 35) == 0)
- {
- $type = basename($value);
- }
- else if (strncmp($value, 'http://oauth.net/core/1.0/signature/', 36) == 0)
- {
- $service['signature_method'][] = basename($value);
- }
- else if (strncmp($value, 'http://oauth.net/core/1.0/parameters/', 37) == 0)
- {
- $service['parameters'][] = basename($value);
- }
- else if (strncmp($value, 'http://oauth.net/discovery/1.0/consumer-identity/', 49) == 0)
- {
- $type = 'consumer_identity';
- $service['method'] = basename($value);
- unset($service['signature_method']);
- unset($service['parameters']);
- }
- else
- {
- $service['unknown'][] = $value;
- }
- }
- else if ($name == 'LocalID')
- {
- $service['consumer_key'] = $value;
- }
- else if ($name{0} != '#')
- {
- $service[strtolower($name)] = $value;
- }
- }
- return array($type, $service);
-}
-
-
-/**
- * Return the OAuth service uris in order of the priority.
- *
- * @param XPath xpath
- * @return array
- */
-function xrds_oauth_service_uris ( $xpath )
-{
- $uris = array();
- $xrd_oauth = $xpath->query('//xrds:XRDS/xrd:XRD/xrd:Service/xrd:Type[.=\'http://oauth.net/discovery/1.0\']');
- if ($xrd_oauth->length > 0)
- {
- $service = array();
- foreach ($xrd_oauth as $xo)
- {
- // Find the URI of the service definition
- $cs = $xo->parentNode->childNodes;
- foreach ($cs as $c)
- {
- if ($c->nodeName == 'URI')
- {
- $prio = xrds_priority($xo);
- $service[$prio][] = $c->nodeValue;
- }
- }
- }
- $uris = xrds_priority_flatten($service);
- }
- return $uris;
-}
-
-
-
-/**
- * Flatten an array according to the priority
- *
- * @param array ps buckets per prio
- * @return array one dimensional array
- */
-function xrds_priority_flatten ( $ps )
-{
- $prio = array();
- $null = array();
- ksort($ps);
- foreach ($ps as $idx => $bucket)
- {
- if (!empty($bucket))
- {
- if ($idx == 'null')
- {
- $null = $bucket;
- }
- else
- {
- $prio = array_merge($prio, $bucket);
- }
- }
- }
- $prio = array_merge($prio, $bucket);
- return $prio;
-}
-
-
-/**
- * Fetch the priority of a element
- *
- * @param DOMElement elt
- * @return mixed 'null' or int
- */
-function xrds_priority ( $elt )
-{
- if ($elt->hasAttribute('priority'))
- {
- $prio = $elt->getAttribute('priority');
- if (is_numeric($prio))
- {
- $prio = intval($prio);
- }
- }
- else
- {
- $prio = 'null';
- }
- return $prio;
-}
-
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/discovery/xrds_parse.txt b/mod/oauth_api/vendors/oauth/library/discovery/xrds_parse.txt
deleted file mode 100644
index fd867ea9f..000000000
--- a/mod/oauth_api/vendors/oauth/library/discovery/xrds_parse.txt
+++ /dev/null
@@ -1,101 +0,0 @@
-The xrds_parse.php script contains the function:
-
- function xrds_parse ( $data. )
-
-$data Contains the contents of a XRDS XML file.
-When the data is invalid XML then this will throw an exception.
-
-After parsing a XRDS definition it will return a datastructure much like the one below.
-
-Array
-(
- [expires] => 2008-04-13T07:34:58Z
- [request] => Array
- (
- [0] => Array
- (
- [uri] => https://ma.gnolia.com/oauth/get_request_token
- [signature_method] => Array
- (
- [0] => HMAC-SHA1
- [1] => RSA-SHA1
- [2] => PLAINTEXT
- )
-
- [parameters] => Array
- (
- [0] => auth-header
- [1] => post-body
- [2] => uri-query
- )
- )
- )
-
- [authorize] => Array
- (
- [0] => Array
- (
- [uri] => http://ma.gnolia.com/oauth/authorize
- [signature_method] => Array
- (
- )
-
- [parameters] => Array
- (
- [0] => auth-header
- [1] => uri-query
- )
- )
- )
-
- [access] => Array
- (
- [0] => Array
- (
- [uri] => https://ma.gnolia.com/oauth/get_access_token
- [signature_method] => Array
- (
- [0] => HMAC-SHA1
- [1] => RSA-SHA1
- [2] => PLAINTEXT
- )
-
- [parameters] => Array
- (
- [0] => auth-header
- [1] => post-body
- [2] => uri-query
- )
- )
- )
-
- [resource] => Array
- (
- [0] => Array
- (
- [uri] =>
- [signature_method] => Array
- (
- [0] => HMAC-SHA1
- [1] => RSA-SHA1
- )
-
- [parameters] => Array
- (
- [0] => auth-header
- [1] => post-body
- [2] => uri-query
- )
- )
- )
-
- [consumer_identity] => Array
- (
- [0] => Array
- (
- [uri] => http://ma.gnolia.com/applications/new
- [method] => oob
- )
- )
-)
-
diff --git a/mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod.class.php b/mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod.class.php
deleted file mode 100644
index 34ccb428c..000000000
--- a/mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod.class.php
+++ /dev/null
@@ -1,69 +0,0 @@
-<?php
-
-/**
- * Interface for OAuth signature methods
- *
- * @version $Id$
- * @author Marc Worrell <marcw@pobox.com>
- * @date Sep 8, 2008 12:04:35 PM
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-abstract class OAuthSignatureMethod
-{
- /**
- * Return the name of this signature
- *
- * @return string
- */
- abstract public function name();
-
- /**
- * Return the signature for the given request
- *
- * @param OAuthRequest request
- * @param string base_string
- * @param string consumer_secret
- * @param string token_secret
- * @return string
- */
- abstract public function signature ( $request, $base_string, $consumer_secret, $token_secret );
-
- /**
- * Check if the request signature corresponds to the one calculated for the request.
- *
- * @param OAuthRequest request
- * @param string base_string data to be signed, usually the base string, can be a request body
- * @param string consumer_secret
- * @param string token_secret
- * @param string signature from the request, still urlencoded
- * @return string
- */
- abstract public function verify ( $request, $base_string, $consumer_secret, $token_secret, $signature );
-}
-
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod_HMAC_SHA1.php b/mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod_HMAC_SHA1.php
deleted file mode 100644
index 4bc949c10..000000000
--- a/mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod_HMAC_SHA1.php
+++ /dev/null
@@ -1,115 +0,0 @@
-<?php
-
-/**
- * OAuth signature implementation using HMAC-SHA1
- *
- * @version $Id$
- * @author Marc Worrell <marcw@pobox.com>
- * @date Sep 8, 2008 12:21:19 PM
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-
-require_once dirname(__FILE__).'/OAuthSignatureMethod.class.php';
-
-
-class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod
-{
- public function name ()
- {
- return 'HMAC-SHA1';
- }
-
-
- /**
- * Calculate the signature using HMAC-SHA1
- * This function is copyright Andy Smith, 2007.
- *
- * @param OAuthRequest request
- * @param string base_string
- * @param string consumer_secret
- * @param string token_secret
- * @return string
- */
- function signature ( $request, $base_string, $consumer_secret, $token_secret )
- {
- $key = $request->urlencode($consumer_secret).'&'.$request->urlencode($token_secret);
- if (function_exists('hash_hmac'))
- {
- $signature = base64_encode(hash_hmac("sha1", $base_string, $key, true));
- }
- else
- {
- $blocksize = 64;
- $hashfunc = 'sha1';
- if (strlen($key) > $blocksize)
- {
- $key = pack('H*', $hashfunc($key));
- }
- $key = str_pad($key,$blocksize,chr(0x00));
- $ipad = str_repeat(chr(0x36),$blocksize);
- $opad = str_repeat(chr(0x5c),$blocksize);
- $hmac = pack(
- 'H*',$hashfunc(
- ($key^$opad).pack(
- 'H*',$hashfunc(
- ($key^$ipad).$base_string
- )
- )
- )
- );
- $signature = base64_encode($hmac);
- }
- return $request->urlencode($signature);
- }
-
-
- /**
- * Check if the request signature corresponds to the one calculated for the request.
- *
- * @param OAuthRequest request
- * @param string base_string data to be signed, usually the base string, can be a request body
- * @param string consumer_secret
- * @param string token_secret
- * @param string signature from the request, still urlencoded
- * @return string
- */
- public function verify ( $request, $base_string, $consumer_secret, $token_secret, $signature )
- {
- $a = $request->urldecode($signature);
- $b = $request->urldecode($this->signature($request, $base_string, $consumer_secret, $token_secret));
-
- // We have to compare the decoded values
- $valA = base64_decode($a);
- $valB = base64_decode($b);
-
- // Crude binary comparison
- return rawurlencode($a) == rawurlencode($b);
- }
-}
-
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod_MD5.php b/mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod_MD5.php
deleted file mode 100644
index 6f593a47f..000000000
--- a/mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod_MD5.php
+++ /dev/null
@@ -1,95 +0,0 @@
-<?php
-
-/**
- * OAuth signature implementation using MD5
- *
- * @version $Id$
- * @author Marc Worrell <marcw@pobox.com>
- * @date Sep 8, 2008 12:09:43 PM
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require_once dirname(__FILE__).'/OAuthSignatureMethod.class.php';
-
-
-class OAuthSignatureMethod_MD5 extends OAuthSignatureMethod
-{
- public function name ()
- {
- return 'MD5';
- }
-
-
- /**
- * Calculate the signature using MD5
- * Binary md5 digest, as distinct from PHP's built-in hexdigest.
- * This function is copyright Andy Smith, 2007.
- *
- * @param OAuthRequest request
- * @param string base_string
- * @param string consumer_secret
- * @param string token_secret
- * @return string
- */
- function signature ( $request, $base_string, $consumer_secret, $token_secret )
- {
- $s .= '&'.$request->urlencode($consumer_secret).'&'.$request->urlencode($token_secret);
- $md5 = md5($base_string);
- $bin = '';
-
- for ($i = 0; $i < strlen($md5); $i += 2)
- {
- $bin .= chr(hexdec($md5{$i+1}) + hexdec($md5{$i}) * 16);
- }
- return $request->urlencode(base64_encode($bin));
- }
-
-
- /**
- * Check if the request signature corresponds to the one calculated for the request.
- *
- * @param OAuthRequest request
- * @param string base_string data to be signed, usually the base string, can be a request body
- * @param string consumer_secret
- * @param string token_secret
- * @param string signature from the request, still urlencoded
- * @return string
- */
- public function verify ( $request, $base_string, $consumer_secret, $token_secret, $signature )
- {
- $a = $request->urldecode($signature);
- $b = $request->urldecode($this->signature($request, $base_string, $consumer_secret, $token_secret));
-
- // We have to compare the decoded values
- $valA = base64_decode($a);
- $valB = base64_decode($b);
-
- // Crude binary comparison
- return rawurlencode($a) == rawurlencode($b);
- }
-}
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod_PLAINTEXT.php b/mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod_PLAINTEXT.php
deleted file mode 100644
index 92ef30867..000000000
--- a/mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod_PLAINTEXT.php
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-
-/**
- * OAuth signature implementation using PLAINTEXT
- *
- * @version $Id$
- * @author Marc Worrell <marcw@pobox.com>
- * @date Sep 8, 2008 12:09:43 PM
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require_once dirname(__FILE__).'/OAuthSignatureMethod.class.php';
-
-
-class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod
-{
- public function name ()
- {
- return 'PLAINTEXT';
- }
-
-
- /**
- * Calculate the signature using PLAINTEXT
- *
- * @param OAuthRequest request
- * @param string base_string
- * @param string consumer_secret
- * @param string token_secret
- * @return string
- */
- function signature ( $request, $base_string, $consumer_secret, $token_secret )
- {
- return $request->urlencode($request->urlencode($consumer_secret).'&'.$request->urlencode($token_secret));
- }
-
-
- /**
- * Check if the request signature corresponds to the one calculated for the request.
- *
- * @param OAuthRequest request
- * @param string base_string data to be signed, usually the base string, can be a request body
- * @param string consumer_secret
- * @param string token_secret
- * @param string signature from the request, still urlencoded
- * @return string
- */
- public function verify ( $request, $base_string, $consumer_secret, $token_secret, $signature )
- {
- $a = $request->urldecode($signature);
- $b = $request->urldecode($this->signature($request, $base_string, $consumer_secret, $token_secret));
-
- return $request->urldecode($a) == $request->urldecode($b);
- }
-}
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod_RSA_SHA1.php b/mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod_RSA_SHA1.php
deleted file mode 100644
index 3bbde7d90..000000000
--- a/mod/oauth_api/vendors/oauth/library/signature_method/OAuthSignatureMethod_RSA_SHA1.php
+++ /dev/null
@@ -1,136 +0,0 @@
-<?php
-
-/**
- * OAuth signature implementation using PLAINTEXT
- *
- * @version $Id$
- * @author Marc Worrell <marcw@pobox.com>
- * @date Sep 8, 2008 12:00:14 PM
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod
-{
- public function name()
- {
- return 'RSA-SHA1';
- }
-
-
- /**
- * Fetch the public CERT key for the signature
- *
- * @param OAuthRequest request
- * @return string public key
- */
- protected function fetch_public_cert ( $request )
- {
- // not implemented yet, ideas are:
- // (1) do a lookup in a table of trusted certs keyed off of consumer
- // (2) fetch via http using a url provided by the requester
- // (3) some sort of specific discovery code based on request
- //
- // either way should return a string representation of the certificate
- throw OAuthException("OAuthSignatureMethod_RSA_SHA1::fetch_public_cert not implemented");
- }
-
-
- /**
- * Fetch the private CERT key for the signature
- *
- * @param OAuthRequest request
- * @return string private key
- */
- protected function fetch_private_cert ( $request )
- {
- // not implemented yet, ideas are:
- // (1) do a lookup in a table of trusted certs keyed off of consumer
- //
- // either way should return a string representation of the certificate
- throw OAuthException("OAuthSignatureMethod_RSA_SHA1::fetch_private_cert not implemented");
- }
-
-
- /**
- * Calculate the signature using RSA-SHA1
- * This function is copyright Andy Smith, 2008.
- *
- * @param OAuthRequest request
- * @param string base_string
- * @param string consumer_secret
- * @param string token_secret
- * @return string
- */
- public function signature ( $request, $base_string, $consumer_secret, $token_secret )
- {
- // Fetch the private key cert based on the request
- $cert = $this->fetch_private_cert($request);
-
- // Pull the private key ID from the certificate
- $privatekeyid = openssl_get_privatekey($cert);
-
- // Sign using the key
- $sig = false;
- $ok = openssl_sign($base_string, $sig, $privatekeyid);
-
- // Release the key resource
- openssl_free_key($privatekeyid);
-
- return $request->urlencode(base64_encode($sig));
- }
-
-
- /**
- * Check if the request signature is the same as the one calculated for the request.
- *
- * @param OAuthRequest request
- * @param string base_string
- * @param string consumer_secret
- * @param string token_secret
- * @param string signature
- * @return string
- */
- public function verify ( $request, $base_string, $consumer_secret, $token_secret, $signature )
- {
- $decoded_sig = base64_decode($request->urldecode($signature));
-
- // Fetch the public key cert based on the request
- $cert = $this->fetch_public_cert($request);
-
- // Pull the public key ID from the certificate
- $publickeyid = openssl_get_publickey($cert);
-
- // Check the computed signature against the one passed in the query
- $ok = openssl_verify($base_string, $decoded_sig, $publickeyid);
-
- // Release the key resource
- openssl_free_key($publickeyid);
- return $ok == 1;
- }
-
-}
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/store/OAuthStoreAbstract.class.php b/mod/oauth_api/vendors/oauth/library/store/OAuthStoreAbstract.class.php
deleted file mode 100644
index e7cca981a..000000000
--- a/mod/oauth_api/vendors/oauth/library/store/OAuthStoreAbstract.class.php
+++ /dev/null
@@ -1,149 +0,0 @@
-<?php
-
-/**
- * Abstract base class for OAuthStore implementations
- *
- * @version $Id$
- * @author Marc Worrell <marcw@pobox.com>
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-abstract class OAuthStoreAbstract
-{
- abstract public function getSecretsForVerify ( $consumer_key, $token, $token_type = 'access' );
- abstract public function getSecretsForSignature ( $uri, $user_id );
- abstract public function getServerTokenSecrets ( $consumer_key, $token, $token_type, $user_id, $name = '' );
- abstract public function addServerToken ( $consumer_key, $token_type, $token, $token_secret, $user_id, $options = array() );
-
- abstract public function deleteServer ( $consumer_key, $user_id, $user_is_admin = false );
- abstract public function getServer( $consumer_key, $user_id, $user_is_admin = false );
- abstract public function getServerForUri ( $uri, $user_id );
- abstract public function listServerTokens ( $user_id );
- abstract public function countServerTokens ( $consumer_key );
- abstract public function getServerToken ( $consumer_key, $token, $user_id );
- abstract public function deleteServerToken ( $consumer_key, $token, $user_id, $user_is_admin = false );
- abstract public function listServers ( $q = '', $user_id );
- abstract public function updateServer ( $server, $user_id, $user_is_admin = false );
-
- abstract public function updateConsumer ( $consumer, $user_id, $user_is_admin = false );
- abstract public function deleteConsumer ( $consumer_key, $user_id, $user_is_admin = false );
- abstract public function getConsumer ( $consumer_key, $user_id, $user_is_admin = false );
- abstract public function getConsumerStatic ();
-
- abstract public function addConsumerRequestToken ( $consumer_key, $options = array() );
- abstract public function getConsumerRequestToken ( $token );
- abstract public function deleteConsumerRequestToken ( $token );
- abstract public function authorizeConsumerRequestToken ( $token, $user_id, $referrer_host = '' );
- abstract public function countConsumerAccessTokens ( $consumer_key );
- abstract public function exchangeConsumerRequestForAccessToken ( $token, $options = array() );
- abstract public function getConsumerAccessToken ( $token, $user_id );
- abstract public function deleteConsumerAccessToken ( $token, $user_id, $user_is_admin = false );
- abstract public function setConsumerAccessTokenTtl ( $token, $ttl );
-
- abstract public function listConsumers ( $user_id );
- abstract public function listConsumerTokens ( $user_id );
-
- abstract public function checkServerNonce ( $consumer_key, $token, $timestamp, $nonce );
-
- abstract public function addLog ( $keys, $received, $sent, $base_string, $notes, $user_id = null );
- abstract public function listLog ( $options, $user_id );
-
- abstract public function install ();
-
- /**
- * Fetch the current static consumer key for this site, create it when it was not found.
- * The consumer secret for the consumer key is always empty.
- *
- * @return string consumer key
- */
-
-
- /* ** Some handy utility functions ** */
-
- /**
- * Generate a unique key
- *
- * @param boolean unique force the key to be unique
- * @return string
- */
- public function generateKey ( $unique = false )
- {
- $key = md5(uniqid(rand(), true));
- if ($unique)
- {
- list($usec,$sec) = explode(' ',microtime());
- $key .= dechex($usec).dechex($sec);
- }
- return $key;
- }
-
- /**
- * Check to see if a string is valid utf8
- *
- * @param string $s
- * @return boolean
- */
- protected function isUTF8 ( $s )
- {
- return preg_match('%(?:
- [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
- |\xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
- |[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
- |\xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
- |\xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
- |[\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
- |\xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
- )+%xs', $s);
- }
-
-
- /**
- * Make a string utf8, replacing all non-utf8 chars with a '.'
- *
- * @param string
- * @return string
- */
- protected function makeUTF8 ( $s )
- {
- if (function_exists('iconv'))
- {
- do
- {
- $ok = true;
- $text = @iconv('UTF-8', 'UTF-8//TRANSLIT', $s);
- if (strlen($text) != strlen($s))
- {
- // Remove the offending character...
- $s = $text . '.' . substr($s, strlen($text) + 1);
- $ok = false;
- }
- }
- while (!$ok);
- }
- return $s;
- }
-
-}
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/store/OAuthStoreAnyMeta.php b/mod/oauth_api/vendors/oauth/library/store/OAuthStoreAnyMeta.php
deleted file mode 100644
index 9c971733f..000000000
--- a/mod/oauth_api/vendors/oauth/library/store/OAuthStoreAnyMeta.php
+++ /dev/null
@@ -1,265 +0,0 @@
-<?php
-
-/**
- * Storage container for the oauth credentials, both server and consumer side.
- * This file can only be used in conjunction with anyMeta.
- *
- * @version $Id: OAuthStoreAnyMeta.php 49 2008-10-01 09:43:19Z marcw@pobox.com $
- * @author Marc Worrell <marcw@pobox.com>
- * @date Nov 16, 2007 4:03:30 PM
- *
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require_once dirname(__FILE__) . '/../../../../core/inc/any_database.inc.php';
-require_once dirname(__FILE__) . '/OAuthStoreMySQL.php';
-
-
-class OAuthStoreAnymeta extends OAuthStoreMySQL
-{
- /**
- * Construct the OAuthStoreAnymeta
- *
- * @param array options
- */
- function __construct ( $options = array() )
- {
- parent::__construct(array('conn' => any_db_conn()));
- }
-
-
- /**
- * Add an entry to the log table
- *
- * @param array keys (osr_consumer_key, ost_token, ocr_consumer_key, oct_token)
- * @param string received
- * @param string sent
- * @param string base_string
- * @param string notes
- * @param int (optional) user_id
- */
- public function addLog ( $keys, $received, $sent, $base_string, $notes, $user_id = null )
- {
- if (is_null($user_id) && isset($GLOBALS['any_auth']))
- {
- $user_id = $GLOBALS['any_auth']->getUserId();
- }
- parent::addLog($keys, $received, $sent, $base_string, $notes, $user_id);
- }
-
-
- /**
- * Get a page of entries from the log. Returns the last 100 records
- * matching the options given.
- *
- * @param array options
- * @param int user_id current user
- * @return array log records
- */
- public function listLog ( $options, $user_id )
- {
- $where = array();
- $args = array();
- if (empty($options))
- {
- $where[] = 'olg_usa_id_ref = %d';
- $args[] = $user_id;
- }
- else
- {
- foreach ($options as $option => $value)
- {
- if (strlen($value) > 0)
- {
- switch ($option)
- {
- case 'osr_consumer_key':
- case 'ocr_consumer_key':
- case 'ost_token':
- case 'oct_token':
- $where[] = 'olg_'.$option.' = \'%s\'';
- $args[] = $value;
- break;
- }
- }
- }
-
- $where[] = '(olg_usa_id_ref IS NULL OR olg_usa_id_ref = %d)';
- $args[] = $user_id;
- }
-
- $rs = any_db_query_all_assoc('
- SELECT olg_id,
- olg_osr_consumer_key AS osr_consumer_key,
- olg_ost_token AS ost_token,
- olg_ocr_consumer_key AS ocr_consumer_key,
- olg_oct_token AS oct_token,
- olg_usa_id_ref AS user_id,
- olg_received AS received,
- olg_sent AS sent,
- olg_base_string AS base_string,
- olg_notes AS notes,
- olg_timestamp AS timestamp,
- INET_NTOA(olg_remote_ip) AS remote_ip
- FROM oauth_log
- WHERE '.implode(' AND ', $where).'
- ORDER BY olg_id DESC
- LIMIT 0,100', $args);
-
- return $rs;
- }
-
-
-
- /**
- * Initialise the database
- */
- public function install ()
- {
- parent::install();
-
- any_db_query("ALTER TABLE oauth_consumer_registry MODIFY ocr_usa_id_ref int(11) unsigned");
- any_db_query("ALTER TABLE oauth_consumer_token MODIFY oct_usa_id_ref int(11) unsigned not null");
- any_db_query("ALTER TABLE oauth_server_registry MODIFY osr_usa_id_ref int(11) unsigned");
- any_db_query("ALTER TABLE oauth_server_token MODIFY ost_usa_id_ref int(11) unsigned not null");
- any_db_query("ALTER TABLE oauth_log MODIFY olg_usa_id_ref int(11) unsigned");
-
- any_db_alter_add_fk('oauth_consumer_registry', 'ocr_usa_id_ref', 'any_user_auth(usa_id_ref)', 'on update cascade on delete set null');
- any_db_alter_add_fk('oauth_consumer_token', 'oct_usa_id_ref', 'any_user_auth(usa_id_ref)', 'on update cascade on delete cascade');
- any_db_alter_add_fk('oauth_server_registry', 'osr_usa_id_ref', 'any_user_auth(usa_id_ref)', 'on update cascade on delete set null');
- any_db_alter_add_fk('oauth_server_token', 'ost_usa_id_ref', 'any_user_auth(usa_id_ref)', 'on update cascade on delete cascade');
- any_db_alter_add_fk('oauth_log', 'olg_usa_id_ref', 'any_user_auth(usa_id_ref)', 'on update cascade on delete cascade');
- }
-
-
-
- /** Some simple helper functions for querying the mysql db **/
-
- /**
- * Perform a query, ignore the results
- *
- * @param string sql
- * @param vararg arguments (for sprintf)
- */
- protected function query ( $sql )
- {
- list($sql, $args) = $this->sql_args(func_get_args());
- any_db_query($sql, $args);
- }
-
-
- /**
- * Perform a query, ignore the results
- *
- * @param string sql
- * @param vararg arguments (for sprintf)
- * @return array
- */
- protected function query_all_assoc ( $sql )
- {
- list($sql, $args) = $this->sql_args(func_get_args());
- return any_db_query_all_assoc($sql, $args);
- }
-
-
- /**
- * Perform a query, return the first row
- *
- * @param string sql
- * @param vararg arguments (for sprintf)
- * @return array
- */
- protected function query_row_assoc ( $sql )
- {
- list($sql, $args) = $this->sql_args(func_get_args());
- return any_db_query_row_assoc($sql, $args);
- }
-
-
- /**
- * Perform a query, return the first row
- *
- * @param string sql
- * @param vararg arguments (for sprintf)
- * @return array
- */
- protected function query_row ( $sql )
- {
- list($sql, $args) = $this->sql_args(func_get_args());
- return any_db_query_row($sql, $args);
- }
-
-
- /**
- * Perform a query, return the first column of the first row
- *
- * @param string sql
- * @param vararg arguments (for sprintf)
- * @return mixed
- */
- protected function query_one ( $sql )
- {
- list($sql, $args) = $this->sql_args(func_get_args());
- return any_db_query_one($sql, $args);
- }
-
-
- /**
- * Return the number of rows affected in the last query
- *
- * @return int
- */
- protected function query_affected_rows ()
- {
- return any_db_affected_rows();
- }
-
-
- /**
- * Return the id of the last inserted row
- *
- * @return int
- */
- protected function query_insert_id ()
- {
- return any_db_insert_id();
- }
-
-
- private function sql_args ( $args )
- {
- $sql = array_shift($args);
- if (count($args) == 1 && is_array($args[0]))
- {
- $args = $args[0];
- }
- return array($sql, $args);
- }
-
-}
-
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/store/OAuthStoreMySQL.php b/mod/oauth_api/vendors/oauth/library/store/OAuthStoreMySQL.php
deleted file mode 100644
index a1b04c5c8..000000000
--- a/mod/oauth_api/vendors/oauth/library/store/OAuthStoreMySQL.php
+++ /dev/null
@@ -1,1879 +0,0 @@
-<?php
-
-/**
- * Storage container for the oauth credentials, both server and consumer side.
- * Based on MySQL
- *
- * @version $Id: OAuthStoreMySQL.php 64 2009-08-16 19:37:00Z marcw@pobox.com $
- * @author Marc Worrell <marcw@pobox.com>
- * @date Nov 16, 2007 4:03:30 PM
- *
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-
-require_once dirname(__FILE__) . '/OAuthStoreAbstract.class.php';
-
-
-class OAuthStoreMySQL extends OAuthStoreAbstract
-{
- /**
- * The MySQL connection
- */
- protected $conn;
-
- /**
- * Maximum delta a timestamp may be off from a previous timestamp.
- * Allows multiple consumers with some clock skew to work with the same token.
- * Unit is seconds, default max skew is 10 minutes.
- */
- protected $max_timestamp_skew = 600;
-
- /**
- * Default ttl for request tokens
- */
- protected $max_request_token_ttl = 3600;
-
-
- /**
- * Construct the OAuthStoreMySQL.
- * In the options you have to supply either:
- * - server, username, password and database (for a mysql_connect)
- * - conn (for the connection to be used)
- *
- * @param array options
- */
- function __construct ( $options = array() )
- {
- if (isset($options['conn']))
- {
- $this->conn = $options['conn'];
- }
- else
- {
- if (isset($options['server']))
- {
- $server = $options['server'];
- $username = $options['username'];
-
- if (isset($options['password']))
- {
- $this->conn = mysql_connect($server, $username, $options['password']);
- }
- else
- {
- $this->conn = mysql_connect($server, $username);
- }
- }
- else
- {
- // Try the default mysql connect
- $this->conn = mysql_connect();
- }
-
- if ($this->conn === false)
- {
- throw new OAuthException('Could not connect to MySQL database: ' . mysql_error());
- }
-
- if (isset($options['database']))
- {
- if (!mysql_select_db($options['database'], $this->conn))
- {
- $this->sql_errcheck();
- }
- }
- $this->query('set character set utf8');
- }
- }
-
-
- /**
- * Find stored credentials for the consumer key and token. Used by an OAuth server
- * when verifying an OAuth request.
- *
- * @param string consumer_key
- * @param string token
- * @param string token_type false, 'request' or 'access'
- * @exception OAuthException when no secrets where found
- * @return array assoc (consumer_secret, token_secret, osr_id, ost_id, user_id)
- */
- public function getSecretsForVerify ( $consumer_key, $token, $token_type = 'access' )
- {
- if ($token_type === false)
- {
- $rs = $this->query_row_assoc('
- SELECT osr_id,
- osr_consumer_key as consumer_key,
- osr_consumer_secret as consumer_secret
- FROM oauth_server_registry
- WHERE osr_consumer_key = \'%s\'
- AND osr_enabled = 1
- ',
- $consumer_key);
-
- if ($rs)
- {
- $rs['token'] = false;
- $rs['token_secret'] = false;
- $rs['user_id'] = false;
- $rs['ost_id'] = false;
- }
- }
- else
- {
- $rs = $this->query_row_assoc('
- SELECT osr_id,
- ost_id,
- ost_usa_id_ref as user_id,
- osr_consumer_key as consumer_key,
- osr_consumer_secret as consumer_secret,
- ost_token as token,
- ost_token_secret as token_secret
- FROM oauth_server_registry
- JOIN oauth_server_token
- ON ost_osr_id_ref = osr_id
- WHERE ost_token_type = \'%s\'
- AND osr_consumer_key = \'%s\'
- AND ost_token = \'%s\'
- AND osr_enabled = 1
- AND ost_token_ttl >= NOW()
- ',
- $token_type, $consumer_key, $token);
- }
-
- if (empty($rs))
- {
- throw new OAuthException('The consumer_key "'.$consumer_key.'" token "'.$token.'" combination does not exist or is not enabled.');
- }
- return $rs;
- }
-
-
- /**
- * Find the server details for signing a request, always looks for an access token.
- * The returned credentials depend on which local user is making the request.
- *
- * The consumer_key must belong to the user or be public (user id is null)
- *
- * For signing we need all of the following:
- *
- * consumer_key consumer key associated with the server
- * consumer_secret consumer secret associated with this server
- * token access token associated with this server
- * token_secret secret for the access token
- * signature_methods signing methods supported by the server (array)
- *
- * @todo filter on token type (we should know how and with what to sign this request, and there might be old access tokens)
- * @param string uri uri of the server
- * @param int user_id id of the logged on user
- * @param string name (optional) name of the token (case sensitive)
- * @exception OAuthException when no credentials found
- * @return array
- */
- public function getSecretsForSignature ( $uri, $user_id, $name = '' )
- {
- // Find a consumer key and token for the given uri
- $ps = parse_url($uri);
- $host = isset($ps['host']) ? $ps['host'] : 'localhost';
- $path = isset($ps['path']) ? $ps['path'] : '';
-
- if (empty($path) || substr($path, -1) != '/')
- {
- $path .= '/';
- }
-
- // The owner of the consumer_key is either the user or nobody (public consumer key)
- $secrets = $this->query_row_assoc('
- SELECT ocr_consumer_key as consumer_key,
- ocr_consumer_secret as consumer_secret,
- oct_token as token,
- oct_token_secret as token_secret,
- ocr_signature_methods as signature_methods
- FROM oauth_consumer_registry
- JOIN oauth_consumer_token ON oct_ocr_id_ref = ocr_id
- WHERE ocr_server_uri_host = \'%s\'
- AND ocr_server_uri_path = LEFT(\'%s\', LENGTH(ocr_server_uri_path))
- AND (ocr_usa_id_ref = %s OR ocr_usa_id_ref IS NULL)
- AND oct_usa_id_ref = %d
- AND oct_token_type = \'access\'
- AND oct_name = \'%s\'
- AND oct_token_ttl >= NOW()
- ORDER BY ocr_usa_id_ref DESC, ocr_consumer_secret DESC, LENGTH(ocr_server_uri_path) DESC
- LIMIT 0,1
- ', $host, $path, $user_id, $user_id, $name
- );
-
- if (empty($secrets))
- {
- throw new OAuthException('No server tokens available for '.$uri);
- }
- $secrets['signature_methods'] = explode(',', $secrets['signature_methods']);
- return $secrets;
- }
-
-
- /**
- * Get the token and token secret we obtained from a server.
- *
- * @param string consumer_key
- * @param string token
- * @param string token_type
- * @param int user_id the user owning the token
- * @param string name optional name for a named token
- * @exception OAuthException when no credentials found
- * @return array
- */
- public function getServerTokenSecrets ( $consumer_key, $token, $token_type, $user_id, $name = '' )
- {
- if ($token_type != 'request' && $token_type != 'access')
- {
- throw new OAuthException('Unkown token type "'.$token_type.'", must be either "request" or "access"');
- }
-
- // Take the most recent token of the given type
- $r = $this->query_row_assoc('
- SELECT ocr_consumer_key as consumer_key,
- ocr_consumer_secret as consumer_secret,
- oct_token as token,
- oct_token_secret as token_secret,
- oct_name as token_name,
- ocr_signature_methods as signature_methods,
- ocr_server_uri as server_uri,
- ocr_request_token_uri as request_token_uri,
- ocr_authorize_uri as authorize_uri,
- ocr_access_token_uri as access_token_uri,
- IF(oct_token_ttl >= \'9999-12-31\', NULL, UNIX_TIMESTAMP(oct_token_ttl) - UNIX_TIMESTAMP(NOW())) as token_ttl
- FROM oauth_consumer_registry
- JOIN oauth_consumer_token
- ON oct_ocr_id_ref = ocr_id
- WHERE ocr_consumer_key = \'%s\'
- AND oct_token_type = \'%s\'
- AND oct_token = \'%s\'
- AND oct_usa_id_ref = %d
- AND oct_token_ttl >= NOW()
- ', $consumer_key, $token_type, $token, $user_id
- );
-
- if (empty($r))
- {
- throw new OAuthException('Could not find a "'.$token_type.'" token for consumer "'.$consumer_key.'" and user '.$user_id);
- }
- if (isset($r['signature_methods']) && !empty($r['signature_methods']))
- {
- $r['signature_methods'] = explode(',',$r['signature_methods']);
- }
- else
- {
- $r['signature_methods'] = array();
- }
- return $r;
- }
-
-
- /**
- * Add a request token we obtained from a server.
- *
- * @todo remove old tokens for this user and this ocr_id
- * @param string consumer_key key of the server in the consumer registry
- * @param string token_type one of 'request' or 'access'
- * @param string token
- * @param string token_secret
- * @param int user_id the user owning the token
- * @param array options extra options, name and token_ttl
- * @exception OAuthException when server is not known
- * @exception OAuthException when we received a duplicate token
- */
- public function addServerToken ( $consumer_key, $token_type, $token, $token_secret, $user_id, $options = array() )
- {
- if ($token_type != 'request' && $token_type != 'access')
- {
- throw new OAuthException('Unknown token type "'.$token_type.'", must be either "request" or "access"');
- }
-
- // Maximum time to live for this token
- if (isset($options['token_ttl']) && is_numeric($options['token_ttl']))
- {
- $ttl = 'DATE_ADD(NOW(), INTERVAL '.intval($options['token_ttl']).' SECOND)';
- }
- else if ($token == 'request')
- {
- $ttl = 'DATE_ADD(NOW(), INTERVAL '.$this->max_request_token_ttl.' SECOND)';
- }
- else
- {
- $ttl = "'9999-12-31'";
- }
-
- $ocr_id = $this->query_one('
- SELECT ocr_id
- FROM oauth_consumer_registry
- WHERE ocr_consumer_key = \'%s\'
- ', $consumer_key);
-
- if (empty($ocr_id))
- {
- throw new OAuthException('No server associated with consumer_key "'.$consumer_key.'"');
- }
-
- // Named tokens, unique per user/consumer key
- if (isset($options['name']) && $options['name'] != '')
- {
- $name = $options['name'];
- }
- else
- {
- $name = '';
- }
-
- // Delete any old tokens with the same type and name for this user/server combination
- $this->query('
- DELETE FROM oauth_consumer_token
- WHERE oct_ocr_id_ref = %d
- AND oct_usa_id_ref = %d
- AND oct_token_type = LOWER(\'%s\')
- AND oct_name = \'%s\'
- ',
- $ocr_id,
- $user_id,
- $token_type,
- $name);
-
- // Insert the new token
- $this->query('
- INSERT IGNORE INTO oauth_consumer_token
- SET oct_ocr_id_ref = %d,
- oct_usa_id_ref = %d,
- oct_name = \'%s\',
- oct_token = \'%s\',
- oct_token_secret= \'%s\',
- oct_token_type = LOWER(\'%s\'),
- oct_timestamp = NOW(),
- oct_token_ttl = '.$ttl.'
- ',
- $ocr_id,
- $user_id,
- $name,
- $token,
- $token_secret,
- $token_type);
-
- if (!$this->query_affected_rows())
- {
- throw new OAuthException('Received duplicate token "'.$token.'" for the same consumer_key "'.$consumer_key.'"');
- }
- }
-
-
- /**
- * Delete a server key. This removes access to that site.
- *
- * @param string consumer_key
- * @param int user_id user registering this server
- * @param boolean user_is_admin
- */
- public function deleteServer ( $consumer_key, $user_id, $user_is_admin = false )
- {
- if ($user_is_admin)
- {
- $this->query('
- DELETE FROM oauth_consumer_registry
- WHERE ocr_consumer_key = \'%s\'
- AND (ocr_usa_id_ref = %d OR ocr_usa_id_ref IS NULL)
- ', $consumer_key, $user_id);
- }
- else
- {
- $this->query('
- DELETE FROM oauth_consumer_registry
- WHERE ocr_consumer_key = \'%s\'
- AND ocr_usa_id_ref = %d
- ', $consumer_key, $user_id);
- }
- }
-
-
- /**
- * Get a server from the consumer registry using the consumer key
- *
- * @param string consumer_key
- * @param int user_id
- * @param boolean user_is_admin (optional)
- * @exception OAuthException when server is not found
- * @return array
- */
- public function getServer ( $consumer_key, $user_id, $user_is_admin = false )
- {
- $r = $this->query_row_assoc('
- SELECT ocr_id as id,
- ocr_usa_id_ref as user_id,
- ocr_consumer_key as consumer_key,
- ocr_consumer_secret as consumer_secret,
- ocr_signature_methods as signature_methods,
- ocr_server_uri as server_uri,
- ocr_request_token_uri as request_token_uri,
- ocr_authorize_uri as authorize_uri,
- ocr_access_token_uri as access_token_uri
- FROM oauth_consumer_registry
- WHERE ocr_consumer_key = \'%s\'
- AND (ocr_usa_id_ref = %d OR ocr_usa_id_ref IS NULL)
- ', $consumer_key, $user_id);
-
- if (empty($r))
- {
- throw new OAuthException('No server with consumer_key "'.$consumer_key.'" has been registered (for this user)');
- }
-
- if (isset($r['signature_methods']) && !empty($r['signature_methods']))
- {
- $r['signature_methods'] = explode(',',$r['signature_methods']);
- }
- else
- {
- $r['signature_methods'] = array();
- }
- return $r;
- }
-
-
-
- /**
- * Find the server details that might be used for a request
- *
- * The consumer_key must belong to the user or be public (user id is null)
- *
- * @param string uri uri of the server
- * @param int user_id id of the logged on user
- * @exception OAuthException when no credentials found
- * @return array
- */
- public function getServerForUri ( $uri, $user_id )
- {
- // Find a consumer key and token for the given uri
- $ps = parse_url($uri);
- $host = isset($ps['host']) ? $ps['host'] : 'localhost';
- $path = isset($ps['path']) ? $ps['path'] : '';
-
- if (empty($path) || substr($path, -1) != '/')
- {
- $path .= '/';
- }
-
- // The owner of the consumer_key is either the user or nobody (public consumer key)
- $server = $this->query_row_assoc('
- SELECT ocr_id as id,
- ocr_usa_id_ref as user_id,
- ocr_consumer_key as consumer_key,
- ocr_consumer_secret as consumer_secret,
- ocr_signature_methods as signature_methods,
- ocr_server_uri as server_uri,
- ocr_request_token_uri as request_token_uri,
- ocr_authorize_uri as authorize_uri,
- ocr_access_token_uri as access_token_uri
- FROM oauth_consumer_registry
- WHERE ocr_server_uri_host = \'%s\'
- AND ocr_server_uri_path = LEFT(\'%s\', LENGTH(ocr_server_uri_path))
- AND (ocr_usa_id_ref = %s OR ocr_usa_id_ref IS NULL)
- ORDER BY ocr_usa_id_ref DESC, consumer_secret DESC, LENGTH(ocr_server_uri_path) DESC
- LIMIT 0,1
- ', $host, $path, $user_id
- );
-
- if (empty($server))
- {
- throw new OAuthException('No server available for '.$uri);
- }
- $server['signature_methods'] = explode(',', $server['signature_methods']);
- return $server;
- }
-
-
- /**
- * Get a list of all server token this user has access to.
- *
- * @param int usr_id
- * @return array
- */
- public function listServerTokens ( $user_id )
- {
- $ts = $this->query_all_assoc('
- SELECT ocr_consumer_key as consumer_key,
- ocr_consumer_secret as consumer_secret,
- oct_id as token_id,
- oct_token as token,
- oct_token_secret as token_secret,
- oct_usa_id_ref as user_id,
- ocr_signature_methods as signature_methods,
- ocr_server_uri as server_uri,
- ocr_server_uri_host as server_uri_host,
- ocr_server_uri_path as server_uri_path,
- ocr_request_token_uri as request_token_uri,
- ocr_authorize_uri as authorize_uri,
- ocr_access_token_uri as access_token_uri,
- oct_timestamp as timestamp
- FROM oauth_consumer_registry
- JOIN oauth_consumer_token
- ON oct_ocr_id_ref = ocr_id
- WHERE oct_usa_id_ref = %d
- AND oct_token_type = \'access\'
- AND oct_token_ttl >= NOW()
- ORDER BY ocr_server_uri_host, ocr_server_uri_path
- ', $user_id);
- return $ts;
- }
-
-
- /**
- * Count how many tokens we have for the given server
- *
- * @param string consumer_key
- * @return int
- */
- public function countServerTokens ( $consumer_key )
- {
- $count = $this->query_one('
- SELECT COUNT(oct_id)
- FROM oauth_consumer_token
- JOIN oauth_consumer_registry
- ON oct_ocr_id_ref = ocr_id
- WHERE oct_token_type = \'access\'
- AND ocr_consumer_key = \'%s\'
- AND oct_token_ttl >= NOW()
- ', $consumer_key);
-
- return $count;
- }
-
-
- /**
- * Get a specific server token for the given user
- *
- * @param string consumer_key
- * @param string token
- * @param int user_id
- * @exception OAuthException when no such token found
- * @return array
- */
- public function getServerToken ( $consumer_key, $token, $user_id )
- {
- $ts = $this->query_row_assoc('
- SELECT ocr_consumer_key as consumer_key,
- ocr_consumer_secret as consumer_secret,
- oct_token as token,
- oct_token_secret as token_secret,
- oct_usa_id_ref as usr_id,
- ocr_signature_methods as signature_methods,
- ocr_server_uri as server_uri,
- ocr_server_uri_host as server_uri_host,
- ocr_server_uri_path as server_uri_path,
- ocr_request_token_uri as request_token_uri,
- ocr_authorize_uri as authorize_uri,
- ocr_access_token_uri as access_token_uri,
- oct_timestamp as timestamp
- FROM oauth_consumer_registry
- JOIN oauth_consumer_token
- ON oct_ocr_id_ref = ocr_id
- WHERE ocr_consumer_key = \'%s\'
- AND oct_usa_id_ref = %d
- AND oct_token_type = \'access\'
- AND oct_token = \'%s\'
- AND oct_token_ttl >= NOW()
- ', $consumer_key, $user_id, $token);
-
- if (empty($ts))
- {
- throw new OAuthException('No such consumer key ('.$consumer_key.') and token ('.$token.') combination for user "'.$user_id.'"');
- }
- return $ts;
- }
-
-
- /**
- * Delete a token we obtained from a server.
- *
- * @param string consumer_key
- * @param string token
- * @param int user_id
- * @param boolean user_is_admin
- */
- public function deleteServerToken ( $consumer_key, $token, $user_id, $user_is_admin = false )
- {
- if ($user_is_admin)
- {
- $this->query('
- DELETE oauth_consumer_token
- FROM oauth_consumer_token
- JOIN oauth_consumer_registry
- ON oct_ocr_id_ref = ocr_id
- WHERE ocr_consumer_key = \'%s\'
- AND oct_token = \'%s\'
- ', $consumer_key, $token);
- }
- else
- {
- $this->query('
- DELETE oauth_consumer_token
- FROM oauth_consumer_token
- JOIN oauth_consumer_registry
- ON oct_ocr_id_ref = ocr_id
- WHERE ocr_consumer_key = \'%s\'
- AND oct_token = \'%s\'
- AND oct_usa_id_ref = %d
- ', $consumer_key, $token, $user_id);
- }
- }
-
-
- /**
- * Set the ttl of a server access token. This is done when the
- * server receives a valid request with a xoauth_token_ttl parameter in it.
- *
- * @param string consumer_key
- * @param string token
- * @param int token_ttl
- */
- public function setServerTokenTtl ( $consumer_key, $token, $token_ttl )
- {
- if ($token_ttl <= 0)
- {
- // Immediate delete when the token is past its ttl
- $this->deleteServerToken($consumer_key, $token, 0, true);
- }
- else
- {
- // Set maximum time to live for this token
- $this->query('
- UPDATE oauth_consumer_token, oauth_consumer_registry
- SET ost_token_ttl = DATE_ADD(NOW(), INTERVAL %d SECOND)
- WHERE ocr_consumer_key = \'%s\'
- AND oct_ocr_id_ref = ocr_id
- AND oct_token = \'%s\'
- ', $token_ttl, $consumer_key, $token);
- }
- }
-
-
- /**
- * Get a list of all consumers from the consumer registry.
- * The consumer keys belong to the user or are public (user id is null)
- *
- * @param string q query term
- * @param int user_id
- * @return array
- */
- public function listServers ( $q = '', $user_id )
- {
- $q = trim(str_replace('%', '', $q));
- $args = array();
-
- if (!empty($q))
- {
- $where = ' WHERE ( ocr_consumer_key like \'%%%s%%\'
- OR ocr_server_uri like \'%%%s%%\'
- OR ocr_server_uri_host like \'%%%s%%\'
- OR ocr_server_uri_path like \'%%%s%%\')
- AND (ocr_usa_id_ref = %d OR ocr_usa_id_ref IS NULL)
- ';
-
- $args[] = $q;
- $args[] = $q;
- $args[] = $q;
- $args[] = $q;
- $args[] = $user_id;
- }
- else
- {
- $where = ' WHERE ocr_usa_id_ref = %d OR ocr_usa_id_ref IS NULL';
- $args[] = $user_id;
- }
-
- $servers = $this->query_all_assoc('
- SELECT ocr_id as id,
- ocr_usa_id_ref as user_id,
- ocr_consumer_key as consumer_key,
- ocr_consumer_secret as consumer_secret,
- ocr_signature_methods as signature_methods,
- ocr_server_uri as server_uri,
- ocr_server_uri_host as server_uri_host,
- ocr_server_uri_path as server_uri_path,
- ocr_request_token_uri as request_token_uri,
- ocr_authorize_uri as authorize_uri,
- ocr_access_token_uri as access_token_uri
- FROM oauth_consumer_registry
- '.$where.'
- ORDER BY ocr_server_uri_host, ocr_server_uri_path
- ', $args);
- return $servers;
- }
-
-
- /**
- * Register or update a server for our site (we will be the consumer)
- *
- * (This is the registry at the consumers, registering servers ;-) )
- *
- * @param array server
- * @param int user_id user registering this server
- * @param boolean user_is_admin
- * @exception OAuthException when fields are missing or on duplicate consumer_key
- * @return consumer_key
- */
- public function updateServer ( $server, $user_id, $user_is_admin = false )
- {
- foreach (array('consumer_key', 'server_uri') as $f)
- {
- if (empty($server[$f]))
- {
- throw new OAuthException('The field "'.$f.'" must be set and non empty');
- }
- }
-
- if (!empty($server['id']))
- {
- $exists = $this->query_one('
- SELECT ocr_id
- FROM oauth_consumer_registry
- WHERE ocr_consumer_key = \'%s\'
- AND ocr_id <> %d
- AND (ocr_usa_id_ref = %d OR ocr_usa_id_ref IS NULL)
- ', $server['consumer_key'], $server['id'], $user_id);
- }
- else
- {
- $exists = $this->query_one('
- SELECT ocr_id
- FROM oauth_consumer_registry
- WHERE ocr_consumer_key = \'%s\'
- AND (ocr_usa_id_ref = %d OR ocr_usa_id_ref IS NULL)
- ', $server['consumer_key'], $user_id);
- }
-
- if ($exists)
- {
- throw new OAuthException('The server with key "'.$server['consumer_key'].'" has already been registered');
- }
-
- $parts = parse_url($server['server_uri']);
- $host = (isset($parts['host']) ? $parts['host'] : 'localhost');
- $path = (isset($parts['path']) ? $parts['path'] : '/');
-
- if (isset($server['signature_methods']))
- {
- if (is_array($server['signature_methods']))
- {
- $server['signature_methods'] = strtoupper(implode(',', $server['signature_methods']));
- }
- }
- else
- {
- $server['signature_methods'] = '';
- }
-
- // When the user is an admin, then the user can update the user_id of this record
- if ($user_is_admin && array_key_exists('user_id', $server))
- {
- if (is_null($server['user_id']))
- {
- $update_user = ', ocr_usa_id_ref = NULL';
- }
- else
- {
- $update_user = ', ocr_usa_id_ref = '.intval($server['user_id']);
- }
- }
- else
- {
- $update_user = '';
- }
-
- if (!empty($server['id']))
- {
- // Check if the current user can update this server definition
- if (!$user_is_admin)
- {
- $ocr_usa_id_ref = $this->query_one('
- SELECT ocr_usa_id_ref
- FROM oauth_consumer_registry
- WHERE ocr_id = %d
- ', $server['id']);
-
- if ($ocr_usa_id_ref != $user_id)
- {
- throw new OAuthException('The user "'.$user_id.'" is not allowed to update this server');
- }
- }
-
- // Update the consumer registration
- $this->query('
- UPDATE oauth_consumer_registry
- SET ocr_consumer_key = \'%s\',
- ocr_consumer_secret = \'%s\',
- ocr_server_uri = \'%s\',
- ocr_server_uri_host = \'%s\',
- ocr_server_uri_path = \'%s\',
- ocr_timestamp = NOW(),
- ocr_request_token_uri = \'%s\',
- ocr_authorize_uri = \'%s\',
- ocr_access_token_uri = \'%s\',
- ocr_signature_methods = \'%s\'
- '.$update_user.'
- WHERE ocr_id = %d
- ',
- $server['consumer_key'],
- $server['consumer_secret'],
- $server['server_uri'],
- strtolower($host),
- $path,
- isset($server['request_token_uri']) ? $server['request_token_uri'] : '',
- isset($server['authorize_uri']) ? $server['authorize_uri'] : '',
- isset($server['access_token_uri']) ? $server['access_token_uri'] : '',
- $server['signature_methods'],
- $server['id']
- );
- }
- else
- {
- if (empty($update_user))
- {
- // Per default the user owning the key is the user registering the key
- $update_user = ', ocr_usa_id_ref = '.intval($user_id);
- }
-
- $this->query('
- INSERT INTO oauth_consumer_registry
- SET ocr_consumer_key = \'%s\',
- ocr_consumer_secret = \'%s\',
- ocr_server_uri = \'%s\',
- ocr_server_uri_host = \'%s\',
- ocr_server_uri_path = \'%s\',
- ocr_timestamp = NOW(),
- ocr_request_token_uri = \'%s\',
- ocr_authorize_uri = \'%s\',
- ocr_access_token_uri = \'%s\',
- ocr_signature_methods = \'%s\'
- '.$update_user,
- $server['consumer_key'],
- $server['consumer_secret'],
- $server['server_uri'],
- strtolower($host),
- $path,
- isset($server['request_token_uri']) ? $server['request_token_uri'] : '',
- isset($server['authorize_uri']) ? $server['authorize_uri'] : '',
- isset($server['access_token_uri']) ? $server['access_token_uri'] : '',
- $server['signature_methods']
- );
-
- $ocr_id = $this->query_insert_id();
- }
- return $server['consumer_key'];
- }
-
-
- /**
- * Insert/update a new consumer with this server (we will be the server)
- * When this is a new consumer, then also generate the consumer key and secret.
- * Never updates the consumer key and secret.
- * When the id is set, then the key and secret must correspond to the entry
- * being updated.
- *
- * (This is the registry at the server, registering consumers ;-) )
- *
- * @param array consumer
- * @param int user_id user registering this consumer
- * @param boolean user_is_admin
- * @return string consumer key
- */
- public function updateConsumer ( $consumer, $user_id, $user_is_admin = false )
- {
- if (!$user_is_admin)
- {
- foreach (array('requester_name', 'requester_email') as $f)
- {
- if (empty($consumer[$f]))
- {
- throw new OAuthException('The field "'.$f.'" must be set and non empty');
- }
- }
- }
-
- if (!empty($consumer['id']))
- {
- if (empty($consumer['consumer_key']))
- {
- throw new OAuthException('The field "consumer_key" must be set and non empty');
- }
- if (!$user_is_admin && empty($consumer['consumer_secret']))
- {
- throw new OAuthException('The field "consumer_secret" must be set and non empty');
- }
-
- // Check if the current user can update this server definition
- if (!$user_is_admin)
- {
- $osr_usa_id_ref = $this->query_one('
- SELECT osr_usa_id_ref
- FROM oauth_server_registry
- WHERE osr_id = %d
- ', $consumer['id']);
-
- if ($osr_usa_id_ref != $user_id)
- {
- throw new OAuthException('The user "'.$user_id.'" is not allowed to update this consumer');
- }
- }
- else
- {
- // User is an admin, allow a key owner to be changed or key to be shared
- if (array_key_exists('user_id',$consumer))
- {
- if (is_null($consumer['user_id']))
- {
- $this->query('
- UPDATE oauth_server_registry
- SET osr_usa_id_ref = NULL
- WHERE osr_id = %d
- ', $consumer['id']);
- }
- else
- {
- $this->query('
- UPDATE oauth_server_registry
- SET osr_usa_id_ref = %d
- WHERE osr_id = %d
- ', $consumer['user_id'], $consumer['id']);
- }
- }
- }
-
- $this->query('
- UPDATE oauth_server_registry
- SET osr_requester_name = \'%s\',
- osr_requester_email = \'%s\',
- osr_callback_uri = \'%s\',
- osr_application_uri = \'%s\',
- osr_application_title = \'%s\',
- osr_application_descr = \'%s\',
- osr_application_notes = \'%s\',
- osr_application_type = \'%s\',
- osr_application_commercial = IF(%d,1,0),
- osr_timestamp = NOW()
- WHERE osr_id = %d
- AND osr_consumer_key = \'%s\'
- AND osr_consumer_secret = \'%s\'
- ',
- $consumer['requester_name'],
- $consumer['requester_email'],
- isset($consumer['callback_uri']) ? $consumer['callback_uri'] : '',
- isset($consumer['application_uri']) ? $consumer['application_uri'] : '',
- isset($consumer['application_title']) ? $consumer['application_title'] : '',
- isset($consumer['application_descr']) ? $consumer['application_descr'] : '',
- isset($consumer['application_notes']) ? $consumer['application_notes'] : '',
- isset($consumer['application_type']) ? $consumer['application_type'] : '',
- isset($consumer['application_commercial']) ? $consumer['application_commercial'] : 0,
- $consumer['id'],
- $consumer['consumer_key'],
- $consumer['consumer_secret']
- );
-
-
- $consumer_key = $consumer['consumer_key'];
- }
- else
- {
- $consumer_key = $this->generateKey(true);
- $consumer_secret= $this->generateKey();
-
- // When the user is an admin, then the user can be forced to something else that the user
- if ($user_is_admin && array_key_exists('user_id',$consumer))
- {
- if (is_null($consumer['user_id']))
- {
- $owner_id = 'NULL';
- }
- else
- {
- $owner_id = intval($consumer['user_id']);
- }
- }
- else
- {
- // No admin, take the user id as the owner id.
- $owner_id = intval($user_id);
- }
-
- $this->query('
- INSERT INTO oauth_server_registry
- SET osr_enabled = 1,
- osr_status = \'active\',
- osr_usa_id_ref = %s,
- osr_consumer_key = \'%s\',
- osr_consumer_secret = \'%s\',
- osr_requester_name = \'%s\',
- osr_requester_email = \'%s\',
- osr_callback_uri = \'%s\',
- osr_application_uri = \'%s\',
- osr_application_title = \'%s\',
- osr_application_descr = \'%s\',
- osr_application_notes = \'%s\',
- osr_application_type = \'%s\',
- osr_application_commercial = IF(%d,1,0),
- osr_timestamp = NOW(),
- osr_issue_date = NOW()
- ',
- $owner_id,
- $consumer_key,
- $consumer_secret,
- $consumer['requester_name'],
- $consumer['requester_email'],
- isset($consumer['callback_uri']) ? $consumer['callback_uri'] : '',
- isset($consumer['application_uri']) ? $consumer['application_uri'] : '',
- isset($consumer['application_title']) ? $consumer['application_title'] : '',
- isset($consumer['application_descr']) ? $consumer['application_descr'] : '',
- isset($consumer['application_notes']) ? $consumer['application_notes'] : '',
- isset($consumer['application_type']) ? $consumer['application_type'] : '',
- isset($consumer['application_commercial']) ? $consumer['application_commercial'] : 0
- );
- }
- return $consumer_key;
-
- }
-
-
-
- /**
- * Delete a consumer key. This removes access to our site for all applications using this key.
- *
- * @param string consumer_key
- * @param int user_id user registering this server
- * @param boolean user_is_admin
- */
- public function deleteConsumer ( $consumer_key, $user_id, $user_is_admin = false )
- {
- if ($user_is_admin)
- {
- $this->query('
- DELETE FROM oauth_server_registry
- WHERE osr_consumer_key = \'%s\'
- AND (osr_usa_id_ref = %d OR osr_usa_id_ref IS NULL)
- ', $consumer_key, $user_id);
- }
- else
- {
- $this->query('
- DELETE FROM oauth_server_registry
- WHERE osr_consumer_key = \'%s\'
- AND osr_usa_id_ref = %d
- ', $consumer_key, $user_id);
- }
- }
-
-
-
- /**
- * Fetch a consumer of this server, by consumer_key.
- *
- * @param string consumer_key
- * @param int user_id
- * @param boolean user_is_admin (optional)
- * @exception OAuthException when consumer not found
- * @return array
- */
- public function getConsumer ( $consumer_key, $user_id, $user_is_admin = false )
- {
- $consumer = $this->query_row_assoc('
- SELECT *
- FROM oauth_server_registry
- WHERE osr_consumer_key = \'%s\'
- ', $consumer_key);
-
- if (!is_array($consumer))
- {
- throw new OAuthException('No consumer with consumer_key "'.$consumer_key.'"');
- }
-
- $c = array();
- foreach ($consumer as $key => $value)
- {
- $c[substr($key, 4)] = $value;
- }
- $c['user_id'] = $c['usa_id_ref'];
-
- if (!$user_is_admin && !empty($c['user_id']) && $c['user_id'] != $user_id)
- {
- throw new OAuthException('No access to the consumer information for consumer_key "'.$consumer_key.'"');
- }
- return $c;
- }
-
-
- /**
- * Fetch the static consumer key for this provider. The user for the static consumer
- * key is NULL (no user, shared key). If the key did not exist then the key is created.
- *
- * @return string
- */
- public function getConsumerStatic ()
- {
- $consumer = $this->query_one('
- SELECT osr_consumer_key
- FROM oauth_server_registry
- WHERE osr_consumer_key LIKE \'sc-%%\'
- AND osr_usa_id_ref IS NULL
- ');
-
- if (empty($consumer))
- {
- $consumer_key = 'sc-'.$this->generateKey(true);
- $this->query('
- INSERT INTO oauth_server_registry
- SET osr_enabled = 1,
- osr_status = \'active\',
- osr_usa_id_ref = NULL,
- osr_consumer_key = \'%s\',
- osr_consumer_secret = \'\',
- osr_requester_name = \'\',
- osr_requester_email = \'\',
- osr_callback_uri = \'\',
- osr_application_uri = \'\',
- osr_application_title = \'Static shared consumer key\',
- osr_application_descr = \'\',
- osr_application_notes = \'Static shared consumer key\',
- osr_application_type = \'\',
- osr_application_commercial = 0,
- osr_timestamp = NOW(),
- osr_issue_date = NOW()
- ',
- $consumer_key
- );
-
- // Just make sure that if the consumer key is truncated that we get the truncated string
- $consumer = $this->getConsumerStatic();
- }
- return $consumer;
- }
-
-
- /**
- * Add an unautorized request token to our server.
- *
- * @param string consumer_key
- * @param array options (eg. token_ttl)
- * @return array (token, token_secret)
- */
- public function addConsumerRequestToken ( $consumer_key, $options = array() )
- {
- $token = $this->generateKey(true);
- $secret = $this->generateKey();
- $osr_id = $this->query_one('
- SELECT osr_id
- FROM oauth_server_registry
- WHERE osr_consumer_key = \'%s\'
- AND osr_enabled = 1
- ', $consumer_key);
-
- if (!$osr_id)
- {
- throw new OAuthException('No server with consumer_key "'.$consumer_key.'" or consumer_key is disabled');
- }
-
- if (isset($options['token_ttl']) && is_numeric($options['token_ttl']))
- {
- $ttl = intval($options['token_ttl']);
- }
- else
- {
- $ttl = $this->max_request_token_ttl;
- }
-
- $this->query('
- INSERT INTO oauth_server_token
- SET ost_osr_id_ref = %d,
- ost_usa_id_ref = 1,
- ost_token = \'%s\',
- ost_token_secret = \'%s\',
- ost_token_type = \'request\',
- ost_token_ttl = DATE_ADD(NOW(), INTERVAL %d SECOND)
- ON DUPLICATE KEY UPDATE
- ost_osr_id_ref = VALUES(ost_osr_id_ref),
- ost_usa_id_ref = VALUES(ost_usa_id_ref),
- ost_token = VALUES(ost_token),
- ost_token_secret = VALUES(ost_token_secret),
- ost_token_type = VALUES(ost_token_type),
- ost_token_ttl = VALUES(ost_token_ttl),
- ost_timestamp = NOW()
- ', $osr_id, $token, $secret, $ttl);
-
- return array('token'=>$token, 'token_secret'=>$secret, 'token_ttl'=>$ttl);
- }
-
-
- /**
- * Fetch the consumer request token, by request token.
- *
- * @param string token
- * @return array token and consumer details
- */
- public function getConsumerRequestToken ( $token )
- {
- $rs = $this->query_row_assoc('
- SELECT ost_token as token,
- ost_token_secret as token_secret,
- osr_consumer_key as consumer_key,
- osr_consumer_secret as consumer_secret,
- ost_token_type as token_type
- FROM oauth_server_token
- JOIN oauth_server_registry
- ON ost_osr_id_ref = osr_id
- WHERE ost_token_type = \'request\'
- AND ost_token = \'%s\'
- AND ost_token_ttl >= NOW()
- ', $token);
-
- return $rs;
- }
-
-
- /**
- * Delete a consumer token. The token must be a request or authorized token.
- *
- * @param string token
- */
- public function deleteConsumerRequestToken ( $token )
- {
- $this->query('
- DELETE FROM oauth_server_token
- WHERE ost_token = \'%s\'
- AND ost_token_type = \'request\'
- ', $token);
- }
-
-
- /**
- * Upgrade a request token to be an authorized request token.
- *
- * @param string token
- * @param int user_id user authorizing the token
- * @param string referrer_host used to set the referrer host for this token, for user feedback
- */
- public function authorizeConsumerRequestToken ( $token, $user_id, $referrer_host = '' )
- {
- $this->query('
- UPDATE oauth_server_token
- SET ost_authorized = 1,
- ost_usa_id_ref = %d,
- ost_timestamp = NOW(),
- ost_referrer_host = \'%s\'
- WHERE ost_token = \'%s\'
- AND ost_token_type = \'request\'
- ', $user_id, $referrer_host, $token);
- }
-
-
- /**
- * Count the consumer access tokens for the given consumer.
- *
- * @param string consumer_key
- * @return int
- */
- public function countConsumerAccessTokens ( $consumer_key )
- {
- $count = $this->query_one('
- SELECT COUNT(ost_id)
- FROM oauth_server_token
- JOIN oauth_server_registry
- ON ost_osr_id_ref = osr_id
- WHERE ost_token_type = \'access\'
- AND osr_consumer_key = \'%s\'
- AND ost_token_ttl >= NOW()
- ', $consumer_key);
-
- return $count;
- }
-
-
- /**
- * Exchange an authorized request token for new access token.
- *
- * @param string token
- * @param array options options for the token, token_ttl
- * @exception OAuthException when token could not be exchanged
- * @return array (token, token_secret)
- */
- public function exchangeConsumerRequestForAccessToken ( $token, $options = array() )
- {
- $new_token = $this->generateKey(true);
- $new_secret = $this->generateKey();
-
- // Maximum time to live for this token
- if (isset($options['token_ttl']) && is_numeric($options['token_ttl']))
- {
- $ttl_sql = 'DATE_ADD(NOW(), INTERVAL '.intval($options['token_ttl']).' SECOND)';
- }
- else
- {
- $ttl_sql = "'9999-12-31'";
- }
-
- $this->query('
- UPDATE oauth_server_token
- SET ost_token = \'%s\',
- ost_token_secret = \'%s\',
- ost_token_type = \'access\',
- ost_timestamp = NOW(),
- ost_token_ttl = '.$ttl_sql.'
- WHERE ost_token = \'%s\'
- AND ost_token_type = \'request\'
- AND ost_authorized = 1
- AND ost_token_ttl >= NOW()
- ', $new_token, $new_secret, $token);
-
- if ($this->query_affected_rows() != 1)
- {
- throw new OAuthException('Can\'t exchange request token "'.$token.'" for access token. No such token or not authorized');
- }
-
- $ret = array('token' => $new_token, 'token_secret' => $new_secret);
- $ttl = $this->query_one('
- SELECT IF(ost_token_ttl >= \'9999-12-31\', NULL, UNIX_TIMESTAMP(ost_token_ttl) - UNIX_TIMESTAMP(NOW())) as token_ttl
- FROM oauth_server_token
- WHERE ost_token = \'%s\'', $new_token);
-
- if (is_numeric($ttl))
- {
- $ret['token_ttl'] = intval($ttl);
- }
- return $ret;
- }
-
-
- /**
- * Fetch the consumer access token, by access token.
- *
- * @param string token
- * @param int user_id
- * @exception OAuthException when token is not found
- * @return array token and consumer details
- */
- public function getConsumerAccessToken ( $token, $user_id )
- {
- $rs = $this->query_row_assoc('
- SELECT ost_token as token,
- ost_token_secret as token_secret,
- ost_referrer_host as token_referrer_host,
- osr_consumer_key as consumer_key,
- osr_consumer_secret as consumer_secret,
- osr_application_uri as application_uri,
- osr_application_title as application_title,
- osr_application_descr as application_descr
- FROM oauth_server_token
- JOIN oauth_server_registry
- ON ost_osr_id_ref = osr_id
- WHERE ost_token_type = \'access\'
- AND ost_token = \'%s\'
- AND ost_usa_id_ref = %d
- AND ost_token_ttl >= NOW()
- ', $token, $user_id);
-
- if (empty($rs))
- {
- throw new OAuthException('No server_token "'.$token.'" for user "'.$user_id.'"');
- }
- return $rs;
- }
-
-
- /**
- * Delete a consumer access token.
- *
- * @param string token
- * @param int user_id
- * @param boolean user_is_admin
- */
- public function deleteConsumerAccessToken ( $token, $user_id, $user_is_admin = false )
- {
- if ($user_is_admin)
- {
- $this->query('
- DELETE FROM oauth_server_token
- WHERE ost_token = \'%s\'
- AND ost_token_type = \'access\'
- ', $token);
- }
- else
- {
- $this->query('
- DELETE FROM oauth_server_token
- WHERE ost_token = \'%s\'
- AND ost_token_type = \'access\'
- AND ost_usa_id_ref = %d
- ', $token, $user_id);
- }
- }
-
-
- /**
- * Set the ttl of a consumer access token. This is done when the
- * server receives a valid request with a xoauth_token_ttl parameter in it.
- *
- * @param string token
- * @param int ttl
- */
- public function setConsumerAccessTokenTtl ( $token, $token_ttl )
- {
- if ($token_ttl <= 0)
- {
- // Immediate delete when the token is past its ttl
- $this->deleteConsumerAccessToken($token, 0, true);
- }
- else
- {
- // Set maximum time to live for this token
- $this->query('
- UPDATE oauth_server_token
- SET ost_token_ttl = DATE_ADD(NOW(), INTERVAL %d SECOND)
- WHERE ost_token = \'%s\'
- AND ost_token_type = \'access\'
- ', $token_ttl, $token);
- }
- }
-
-
- /**
- * Fetch a list of all consumer keys, secrets etc.
- * Returns the public (user_id is null) and the keys owned by the user
- *
- * @param int user_id
- * @return array
- */
- public function listConsumers ( $user_id )
- {
- $rs = $this->query_all_assoc('
- SELECT osr_id as id,
- osr_usa_id_ref as user_id,
- osr_consumer_key as consumer_key,
- osr_consumer_secret as consumer_secret,
- osr_enabled as enabled,
- osr_status as status,
- osr_issue_date as issue_date,
- osr_application_uri as application_uri,
- osr_application_title as application_title,
- osr_application_descr as application_descr,
- osr_requester_name as requester_name,
- osr_requester_email as requester_email
- FROM oauth_server_registry
- WHERE (osr_usa_id_ref = %d OR osr_usa_id_ref IS NULL)
- ORDER BY osr_application_title
- ', $user_id);
- return $rs;
- }
-
-
- /**
- * Fetch a list of all consumer tokens accessing the account of the given user.
- *
- * @param int user_id
- * @return array
- */
- public function listConsumerTokens ( $user_id )
- {
- $rs = $this->query_all_assoc('
- SELECT osr_consumer_key as consumer_key,
- osr_consumer_secret as consumer_secret,
- osr_enabled as enabled,
- osr_status as status,
- osr_application_uri as application_uri,
- osr_application_title as application_title,
- osr_application_descr as application_descr,
- ost_timestamp as timestamp,
- ost_token as token,
- ost_token_secret as token_secret,
- ost_referrer_host as token_referrer_host
- FROM oauth_server_registry
- JOIN oauth_server_token
- ON ost_osr_id_ref = osr_id
- WHERE ost_usa_id_ref = %d
- AND ost_token_type = \'access\'
- AND ost_token_ttl >= NOW()
- ORDER BY osr_application_title
- ', $user_id);
- return $rs;
- }
-
-
- /**
- * Check an nonce/timestamp combination. Clears any nonce combinations
- * that are older than the one received.
- *
- * @param string consumer_key
- * @param string token
- * @param int timestamp
- * @param string nonce
- * @exception OAuthException thrown when the timestamp is not in sequence or nonce is not unique
- */
- public function checkServerNonce ( $consumer_key, $token, $timestamp, $nonce )
- {
- $r = $this->query_row('
- SELECT MAX(osn_timestamp), MAX(osn_timestamp) > %d + %d
- FROM oauth_server_nonce
- WHERE osn_consumer_key = \'%s\'
- AND osn_token = \'%s\'
- ', $timestamp, $this->max_timestamp_skew, $consumer_key, $token);
-
- if (!empty($r) && $r[1])
- {
- throw new OAuthException('Timestamp is out of sequence. Request rejected. Got '.$timestamp.' last max is '.$r[0].' allowed skew is '.$this->max_timestamp_skew);
- }
-
- // Insert the new combination
- $this->query('
- INSERT IGNORE INTO oauth_server_nonce
- SET osn_consumer_key = \'%s\',
- osn_token = \'%s\',
- osn_timestamp = %d,
- osn_nonce = \'%s\'
- ', $consumer_key, $token, $timestamp, $nonce);
-
- if ($this->query_affected_rows() == 0)
- {
- throw new OAuthException('Duplicate timestamp/nonce combination, possible replay attack. Request rejected.');
- }
-
- // Clean up all timestamps older than the one we just received
- $this->query('
- DELETE FROM oauth_server_nonce
- WHERE osn_consumer_key = \'%s\'
- AND osn_token = \'%s\'
- AND osn_timestamp < %d - %d
- ', $consumer_key, $token, $timestamp, $this->max_timestamp_skew);
- }
-
-
- /**
- * Add an entry to the log table
- *
- * @param array keys (osr_consumer_key, ost_token, ocr_consumer_key, oct_token)
- * @param string received
- * @param string sent
- * @param string base_string
- * @param string notes
- * @param int (optional) user_id
- */
- public function addLog ( $keys, $received, $sent, $base_string, $notes, $user_id = null )
- {
- $args = array();
- $ps = array();
- foreach ($keys as $key => $value)
- {
- $args[] = $value;
- $ps[] = "olg_$key = '%s'";
- }
-
- if (!empty($_SERVER['REMOTE_ADDR']))
- {
- $remote_ip = $_SERVER['REMOTE_ADDR'];
- }
- else if (!empty($_SERVER['REMOTE_IP']))
- {
- $remote_ip = $_SERVER['REMOTE_IP'];
- }
- else
- {
- $remote_ip = '0.0.0.0';
- }
-
- // Build the SQL
- $ps[] = "olg_received = '%s'"; $args[] = $this->makeUTF8($received);
- $ps[] = "olg_sent = '%s'"; $args[] = $this->makeUTF8($sent);
- $ps[] = "olg_base_string= '%s'"; $args[] = $base_string;
- $ps[] = "olg_notes = '%s'"; $args[] = $this->makeUTF8($notes);
- $ps[] = "olg_usa_id_ref = NULLIF(%d,0)"; $args[] = $user_id;
- $ps[] = "olg_remote_ip = IFNULL(INET_ATON('%s'),0)"; $args[] = $remote_ip;
-
- $this->query('INSERT INTO oauth_log SET '.implode(',', $ps), $args);
- }
-
-
- /**
- * Get a page of entries from the log. Returns the last 100 records
- * matching the options given.
- *
- * @param array options
- * @param int user_id current user
- * @return array log records
- */
- public function listLog ( $options, $user_id )
- {
- $where = array();
- $args = array();
- if (empty($options))
- {
- $where[] = 'olg_usa_id_ref = %d';
- $args[] = $user_id;
- }
- else
- {
- foreach ($options as $option => $value)
- {
- if (strlen($value) > 0)
- {
- switch ($option)
- {
- case 'osr_consumer_key':
- case 'ocr_consumer_key':
- case 'ost_token':
- case 'oct_token':
- $where[] = 'olg_'.$option.' = \'%s\'';
- $args[] = $value;
- break;
- }
- }
- }
-
- $where[] = '(olg_usa_id_ref IS NULL OR olg_usa_id_ref = %d)';
- $args[] = $user_id;
- }
-
- $rs = $this->query_all_assoc('
- SELECT olg_id,
- olg_osr_consumer_key AS osr_consumer_key,
- olg_ost_token AS ost_token,
- olg_ocr_consumer_key AS ocr_consumer_key,
- olg_oct_token AS oct_token,
- olg_usa_id_ref AS user_id,
- olg_received AS received,
- olg_sent AS sent,
- olg_base_string AS base_string,
- olg_notes AS notes,
- olg_timestamp AS timestamp,
- INET_NTOA(olg_remote_ip) AS remote_ip
- FROM oauth_log
- WHERE '.implode(' AND ', $where).'
- ORDER BY olg_id DESC
- LIMIT 0,100', $args);
-
- return $rs;
- }
-
-
-
- /**
- * Initialise the database
- */
- public function install ()
- {
- require_once dirname(__FILE__) . '/mysql/install.php';
- }
-
-
- /* ** Some simple helper functions for querying the mysql db ** */
-
- /**
- * Perform a query, ignore the results
- *
- * @param string sql
- * @param vararg arguments (for sprintf)
- */
- protected function query ( $sql )
- {
- $sql = $this->sql_printf(func_get_args());
- if (!($res = mysql_query($sql, $this->conn)))
- {
- $this->sql_errcheck($sql);
- }
- if (is_resource($res))
- {
- mysql_free_result($res);
- }
- }
-
-
- /**
- * Perform a query, ignore the results
- *
- * @param string sql
- * @param vararg arguments (for sprintf)
- * @return array
- */
- protected function query_all_assoc ( $sql )
- {
- $sql = $this->sql_printf(func_get_args());
- if (!($res = mysql_query($sql, $this->conn)))
- {
- $this->sql_errcheck($sql);
- }
- $rs = array();
- while ($row = mysql_fetch_assoc($res))
- {
- $rs[] = $row;
- }
- mysql_free_result($res);
- return $rs;
- }
-
-
- /**
- * Perform a query, return the first row
- *
- * @param string sql
- * @param vararg arguments (for sprintf)
- * @return array
- */
- protected function query_row_assoc ( $sql )
- {
- $sql = $this->sql_printf(func_get_args());
- if (!($res = mysql_query($sql, $this->conn)))
- {
- $this->sql_errcheck($sql);
- }
- if ($row = mysql_fetch_assoc($res))
- {
- $rs = $row;
- }
- else
- {
- $rs = false;
- }
- mysql_free_result($res);
- return $rs;
- }
-
-
- /**
- * Perform a query, return the first row
- *
- * @param string sql
- * @param vararg arguments (for sprintf)
- * @return array
- */
- protected function query_row ( $sql )
- {
- $sql = $this->sql_printf(func_get_args());
- if (!($res = mysql_query($sql, $this->conn)))
- {
- $this->sql_errcheck($sql);
- }
- if ($row = mysql_fetch_array($res))
- {
- $rs = $row;
- }
- else
- {
- $rs = false;
- }
- mysql_free_result($res);
- return $rs;
- }
-
-
- /**
- * Perform a query, return the first column of the first row
- *
- * @param string sql
- * @param vararg arguments (for sprintf)
- * @return mixed
- */
- protected function query_one ( $sql )
- {
- $sql = $this->sql_printf(func_get_args());
- if (!($res = mysql_query($sql, $this->conn)))
- {
- $this->sql_errcheck($sql);
- }
- $val = @mysql_result($res, 0, 0);
- mysql_free_result($res);
- return $val;
- }
-
-
- /**
- * Return the number of rows affected in the last query
- */
- protected function query_affected_rows ()
- {
- return mysql_affected_rows($this->conn);
- }
-
-
- /**
- * Return the id of the last inserted row
- *
- * @return int
- */
- protected function query_insert_id ()
- {
- return mysql_insert_id($this->conn);
- }
-
-
- protected function sql_printf ( $args )
- {
- $sql = array_shift($args);
- if (count($args) == 1 && is_array($args[0]))
- {
- $args = $args[0];
- }
- $args = array_map(array($this, 'sql_escape_string'), $args);
- return vsprintf($sql, $args);
- }
-
-
- protected function sql_escape_string ( $s )
- {
- if (is_string($s))
- {
- return mysql_real_escape_string($s, $this->conn);
- }
- else if (is_null($s))
- {
- return NULL;
- }
- else if (is_bool($s))
- {
- return intval($s);
- }
- else if (is_int($s) || is_float($s))
- {
- return $s;
- }
- else
- {
- return mysql_real_escape_string(strval($s), $this->conn);
- }
- }
-
-
- protected function sql_errcheck ( $sql )
- {
- if (mysql_errno($this->conn))
- {
- $msg = "SQL Error in OAuthStoreMySQL: ".mysql_error($this->conn)."\n\n" . $sql;
- throw new OAuthException($msg);
- }
- }
-}
-
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/store/mysql/install.php b/mod/oauth_api/vendors/oauth/library/store/mysql/install.php
deleted file mode 100644
index 0015da5e3..000000000
--- a/mod/oauth_api/vendors/oauth/library/store/mysql/install.php
+++ /dev/null
@@ -1,32 +0,0 @@
-<?php
-
-/**
- * Installs all tables in the mysql.sql file, using the default mysql connection
- */
-
-/* Change and uncomment this when you need to: */
-
-/*
-mysql_connect('localhost', 'root');
-if (mysql_errno())
-{
- die(' Error '.mysql_errno().': '.mysql_error());
-}
-mysql_select_db('test');
-*/
-
-$sql = file_get_contents(dirname(__FILE__) . '/mysql.sql');
-$ps = explode('#--SPLIT--', $sql);
-
-foreach ($ps as $p)
-{
- $p = preg_replace('/^\s*#.*$/m', '', $p);
-
- mysql_query($p);
- if (mysql_errno())
- {
- die(' Error '.mysql_errno().': '.mysql_error());
- }
-}
-
-?> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/library/store/mysql/mysql.sql b/mod/oauth_api/vendors/oauth/library/store/mysql/mysql.sql
deleted file mode 100644
index d652a1c99..000000000
--- a/mod/oauth_api/vendors/oauth/library/store/mysql/mysql.sql
+++ /dev/null
@@ -1,219 +0,0 @@
-# Datamodel for OAuthStoreMySQL
-#
-# You need to add the foreign key constraints for the user ids your are using.
-# I have commented the constraints out, just look for 'usa_id_ref' to enable them.
-#
-# The --SPLIT-- markers are used by the install.php script
-#
-# @version $Id: mysql.sql 51 2008-10-15 15:15:47Z marcw@pobox.com $
-# @author Marc Worrell
-#
-
-# Changes:
-#
-# 2008-10-15 (on r48) Added ttl to consumer and server tokens, added named server tokens
-#
-# ALTER TABLE oauth_server_token
-# ADD ost_token_ttl datetime not null default '9999-12-31',
-# ADD KEY (ost_token_ttl);
-#
-# ALTER TABLE oauth_consumer_token
-# ADD oct_name varchar(64) binary not null default '',
-# ADD oct_token_ttl datetime not null default '9999-12-31',
-# DROP KEY oct_usa_id_ref,
-# ADD UNIQUE KEY (oct_usa_id_ref, oct_ocr_id_ref, oct_token_type, oct_name),
-# ADD KEY (oct_token_ttl);
-#
-# 2008-09-09 (on r5) Added referrer host to server access token
-#
-# ALTER TABLE oauth_server_token ADD ost_referrer_host VARCHAR(128) NOT NULL;
-#
-
-
-#
-# Log table to hold all OAuth request when you enabled logging
-#
-
-CREATE TABLE IF NOT EXISTS oauth_log (
- olg_id int(11) not null auto_increment,
- olg_osr_consumer_key varchar(64) binary,
- olg_ost_token varchar(64) binary,
- olg_ocr_consumer_key varchar(64) binary,
- olg_oct_token varchar(64) binary,
- olg_usa_id_ref int(11),
- olg_received text not null,
- olg_sent text not null,
- olg_base_string text not null,
- olg_notes text not null,
- olg_timestamp timestamp not null default current_timestamp,
- olg_remote_ip bigint not null,
-
- primary key (olg_id),
- key (olg_osr_consumer_key, olg_id),
- key (olg_ost_token, olg_id),
- key (olg_ocr_consumer_key, olg_id),
- key (olg_oct_token, olg_id),
- key (olg_usa_id_ref, olg_id)
-
-# , foreign key (olg_usa_id_ref) references any_user_auth (usa_id_ref)
-# on update cascade
-# on delete cascade
-) engine=InnoDB default charset=utf8;
-
-#--SPLIT--
-
-#
-# /////////////////// CONSUMER SIDE ///////////////////
-#
-
-# This is a registry of all consumer codes we got from other servers
-# The consumer_key/secret is obtained from the server
-# We also register the server uri, so that we can find the consumer key and secret
-# for a certain server. From that server we can check if we have a token for a
-# particular user.
-
-CREATE TABLE IF NOT EXISTS oauth_consumer_registry (
- ocr_id int(11) not null auto_increment,
- ocr_usa_id_ref int(11),
- ocr_consumer_key varchar(64) binary not null,
- ocr_consumer_secret varchar(64) binary not null,
- ocr_signature_methods varchar(255) not null default 'HMAC-SHA1,PLAINTEXT',
- ocr_server_uri varchar(255) not null,
- ocr_server_uri_host varchar(128) not null,
- ocr_server_uri_path varchar(128) binary not null,
-
- ocr_request_token_uri varchar(255) not null,
- ocr_authorize_uri varchar(255) not null,
- ocr_access_token_uri varchar(255) not null,
- ocr_timestamp timestamp not null default current_timestamp,
-
- primary key (ocr_id),
- unique key (ocr_consumer_key, ocr_usa_id_ref),
- key (ocr_server_uri),
- key (ocr_server_uri_host, ocr_server_uri_path),
- key (ocr_usa_id_ref)
-
-# , foreign key (ocr_usa_id_ref) references any_user_auth(usa_id_ref)
-# on update cascade
-# on delete set null
-) engine=InnoDB default charset=utf8;
-
-#--SPLIT--
-
-# Table used to sign requests for sending to a server by the consumer
-# The key is defined for a particular user. Only one single named
-# key is allowed per user/server combination
-
-CREATE TABLE IF NOT EXISTS oauth_consumer_token (
- oct_id int(11) not null auto_increment,
- oct_ocr_id_ref int(11) not null,
- oct_usa_id_ref int(11) not null,
- oct_name varchar(64) binary not null default '',
- oct_token varchar(64) binary not null,
- oct_token_secret varchar(64) binary not null,
- oct_token_type enum('request','authorized','access'),
- oct_token_ttl datetime not null default '9999-12-31',
- oct_timestamp timestamp not null default current_timestamp,
-
- primary key (oct_id),
- unique key (oct_ocr_id_ref, oct_token),
- unique key (oct_usa_id_ref, oct_ocr_id_ref, oct_token_type, oct_name),
- key (oct_token_ttl),
-
- foreign key (oct_ocr_id_ref) references oauth_consumer_registry (ocr_id)
- on update cascade
- on delete cascade
-
-# , foreign key (oct_usa_id_ref) references any_user_auth (usa_id_ref)
-# on update cascade
-# on delete cascade
-) engine=InnoDB default charset=utf8;
-
-#--SPLIT--
-
-
-#
-# ////////////////// SERVER SIDE /////////////////
-#
-
-# Table holding consumer key/secret combos an user issued to consumers.
-# Used for verification of incoming requests.
-
-CREATE TABLE IF NOT EXISTS oauth_server_registry (
- osr_id int(11) not null auto_increment,
- osr_usa_id_ref int(11),
- osr_consumer_key varchar(64) binary not null,
- osr_consumer_secret varchar(64) binary not null,
- osr_enabled tinyint(1) not null default '1',
- osr_status varchar(16) not null,
- osr_requester_name varchar(64) not null,
- osr_requester_email varchar(64) not null,
- osr_callback_uri varchar(255) not null,
- osr_application_uri varchar(255) not null,
- osr_application_title varchar(80) not null,
- osr_application_descr text not null,
- osr_application_notes text not null,
- osr_application_type varchar(20) not null,
- osr_application_commercial tinyint(1) not null default '0',
- osr_issue_date datetime not null,
- osr_timestamp timestamp not null default current_timestamp,
-
- primary key (osr_id),
- unique key (osr_consumer_key),
- key (osr_usa_id_ref)
-
-# , foreign key (osr_usa_id_ref) references any_user_auth(usa_id_ref)
-# on update cascade
-# on delete set null
-) engine=InnoDB default charset=utf8;
-
-#--SPLIT--
-
-# Nonce used by a certain consumer, every used nonce should be unique, this prevents
-# replaying attacks. We need to store all timestamp/nonce combinations for the
-# maximum timestamp received.
-
-CREATE TABLE IF NOT EXISTS oauth_server_nonce (
- osn_id int(11) not null auto_increment,
- osn_consumer_key varchar(64) binary not null,
- osn_token varchar(64) binary not null,
- osn_timestamp bigint not null,
- osn_nonce varchar(80) binary not null,
-
- primary key (osn_id),
- unique key (osn_consumer_key, osn_token, osn_timestamp, osn_nonce)
-) engine=InnoDB default charset=utf8;
-
-#--SPLIT--
-
-# Table used to verify signed requests sent to a server by the consumer
-# When the verification is succesful then the associated user id is returned.
-
-CREATE TABLE IF NOT EXISTS oauth_server_token (
- ost_id int(11) not null auto_increment,
- ost_osr_id_ref int(11) not null,
- ost_usa_id_ref int(11) not null,
- ost_token varchar(64) binary not null,
- ost_token_secret varchar(64) binary not null,
- ost_token_type enum('request','access'),
- ost_authorized tinyint(1) not null default '0',
- ost_referrer_host varchar(128) not null,
- ost_token_ttl datetime not null default '9999-12-31',
- ost_timestamp timestamp not null default current_timestamp,
-
- primary key (ost_id),
- unique key (ost_token),
- key (ost_osr_id_ref),
- key (ost_token_ttl),
-
- foreign key (ost_osr_id_ref) references oauth_server_registry (osr_id)
- on update cascade
- on delete cascade
-
-# , foreign key (ost_usa_id_ref) references any_user_auth (usa_id_ref)
-# on update cascade
-# on delete cascade
-) engine=InnoDB default charset=utf8;
-
-
-
diff --git a/mod/oauth_api/vendors/oauth/test/discovery/xrds-fireeagle.xrds b/mod/oauth_api/vendors/oauth/test/discovery/xrds-fireeagle.xrds
deleted file mode 100644
index 0f5eba222..000000000
--- a/mod/oauth_api/vendors/oauth/test/discovery/xrds-fireeagle.xrds
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<XRDS xmlns="xri://$xrds">
-
- <!-- FireEagle User-Centric OAuth Configuration -->
- <XRD xml:id="oauth" xmlns:simple="http://xrds-simple.net/core/1.0" xmlns="xri://$XRD*($v*2.0)" version="2.0">
-
- <Type>xri://$xrds*simple</Type>
- <Expires>2008-04-15T00:25:30-07:00</Expires>
-
- <!-- Request Token -->
- <Service>
- <Type>http://oauth.net/core/1.0/endpoint/request</Type>
-
- <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
- <Type>http://oauth.net/core/1.0/parameters/post-body</Type>
- <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
- <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
- <Type>http://oauth.net/core/1.0/signature/PLAINTEXT</Type>
-
- <URI>https://fireeagle.yahooapis.com/oauth/request_token</URI>
- </Service>
-
- <!-- User Authorization -->
- <Service>
- <Type>http://oauth.net/core/1.0/endpoint/authorize</Type>
-
- <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
- <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
-
- <URI>https://fireeagle.yahooapis.com/oauth/access_token</URI>
- </Service>
-
- <!-- Access Token -->
- <Service>
- <Type>http://oauth.net/core/1.0/endpoint/access</Type>
-
- <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
- <Type>http://oauth.net/core/1.0/parameters/post-body</Type>
- <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
- <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
- <Type>http://oauth.net/core/1.0/signature/PLAINTEXT</Type>
-
- <URI>http://fireeagle.yahoo.net/oauth/authorize</URI>
- </Service>
-
- <!-- Protected Resources -->
- <Service>
- <Type>http://oauth.net/core/1.0/endpoint/resource</Type>
-
- <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
- <Type>http://oauth.net/core/1.0/parameters/post-body</Type>
- <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
- <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
- <Type>http://oauth.net/core/1.0/signature/PLAINTEXT</Type>
- </Service>
-
- <!-- Consumer Identity -->
-
- <!-- Manual Consumer Identity Allocation -->
- <Service>
- <Type>http://oauth.net/discovery/1.0/consumer-identity/oob</Type>
- <URI>https://fireeagle.yahoo.net/developer/create</URI>
- </Service>
- </XRD>
-
- <!-- Global Resource Definition -->
-
- <XRD xmlns="xri://$XRD*($v*2.0)" version="2.0">
- <Type>xri://$xrds*simple</Type>
-
- <!-- OAuth Endpoints Definition -->
- <Service>
- <Type>http://oauth.net/discovery/1.0</Type>
- <URI>#oauth</URI>
- </Service>
- </XRD>
-
-</XRDS> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/test/discovery/xrds-getsatisfaction.xrds b/mod/oauth_api/vendors/oauth/test/discovery/xrds-getsatisfaction.xrds
deleted file mode 100644
index ab94b5bea..000000000
--- a/mod/oauth_api/vendors/oauth/test/discovery/xrds-getsatisfaction.xrds
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<XRDS xmlns="xri://$xrds">
-
- <XRD xml:id="oauth" xmlns:simple="http://xrds-simple.net/core/1.0" xmlns="xri://$XRD*($v*2.0)" version="2.0">
- <Type>xri://$xrds*simple</Type>
- <Expires>2008-04-30T23:59:59Z</Expires>
-
- <!-- Request Token -->
- <Service>
- <Type>http://oauth.net/core/1.0/endpoint/request</Type>
-
- <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
- <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
-
- <URI>http://getsatisfaction.com/api/request_token</URI>
- </Service>
-
- <Service>
- <Type>http://oauth.net/core/1.0/endpoint/authorize</Type>
-
- <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
-
- <URI>http://getsatisfaction.com/api/authorize</URI>
- </Service>
-
- <!-- Access Token -->
- <Service>
- <Type>http://oauth.net/core/1.0/endpoint/access</Type>
-
- <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
- <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
-
- <URI>http://getsatisfaction.com/api/access_token</URI>
- </Service>
-
- <!-- Protected Resources -->
- <!--
-
- To test successful access token grant, make a request against
-
- http://api.getsatisfaction.com/me
-
- The API should respond with hCard of the user who authorized the token
- -->
- <Service>
- <Type>http://oauth.net/core/1.0/endpoint/resource</Type>
-
- <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
- <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
-
- </Service>
-
- <!-- Consumer Identity -->
-
- <Service>
- <Type>http://oauth.net/discovery/1.0/consumer-identity/oob</Type>
- <URI>http://getsatisfaction.com/me/extensions/new</URI>
- </Service>
- </XRD>
-
- <!-- Global Resource Definition -->
-
- <XRD xmlns="xri://$XRD*($v*2.0)" version="2.0">
- <Type>xri://$xrds*simple</Type>
-
- <!-- OAuth Endpoints Definition -->
- <Service priority="10">
- <Type>http://oauth.net/discovery/1.0</Type>
- <URI>#oauth</URI>
- </Service>
- </XRD>
-
-</XRDS> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/test/discovery/xrds-magnolia.xrds b/mod/oauth_api/vendors/oauth/test/discovery/xrds-magnolia.xrds
deleted file mode 100644
index 361b5c9a1..000000000
--- a/mod/oauth_api/vendors/oauth/test/discovery/xrds-magnolia.xrds
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<XRDS xmlns="xri://$xrds">
-
- <!-- Ma.gnolia OAuth Configuration -->
- <XRD xml:id="oauth" xmlns="xri://$XRD*($v*2.0)" version="2.0">
-
- <Type>xri://$xrds*simple</Type>
- <Expires>2008-04-13T07:34:58Z</Expires>
-
- <!-- Request Token -->
- <Service>
- <Type>http://oauth.net/core/1.0/endpoint/request</Type>
-
- <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
- <Type>http://oauth.net/core/1.0/parameters/post-body</Type>
- <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
- <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
- <Type>http://oauth.net/core/1.0/signature/RSA-SHA1</Type>
- <Type>http://oauth.net/core/1.0/signature/PLAINTEXT</Type>
-
- <URI>https://ma.gnolia.com/oauth/get_request_token</URI>
- </Service>
-
- <!-- User Authorization (HTTPS Prefered) -->
- <Service>
- <Type>http://oauth.net/core/1.0/endpoint/authorize</Type>
-
- <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
- <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
-
- <URI priority="10">https://ma.gnolia.com/oauth/authorize</URI>
- <URI priority="20">http://ma.gnolia.com/oauth/authorize</URI>
- </Service>
-
- <!-- Access Token -->
- <Service>
- <Type>http://oauth.net/core/1.0/endpoint/access</Type>
-
- <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
- <Type>http://oauth.net/core/1.0/parameters/post-body</Type>
- <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
- <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
- <Type>http://oauth.net/core/1.0/signature/RSA-SHA1</Type>
- <Type>http://oauth.net/core/1.0/signature/PLAINTEXT</Type>
-
- <URI>https://ma.gnolia.com/oauth/get_access_token</URI>
- </Service>
-
- <!-- Protected Resources -->
- <Service>
- <Type>http://oauth.net/core/1.0/endpoint/resource</Type>
-
- <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
- <Type>http://oauth.net/core/1.0/parameters/post-body</Type>
- <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
- <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
- <Type>http://oauth.net/core/1.0/signature/RSA-SHA1</Type>
- </Service>
-
- <!-- Consumer Identity -->
-
- <!-- Manual Consumer Identity Allocation -->
- <Service>
- <Type>http://oauth.net/discovery/1.0/consumer-identity/oob</Type>
- <URI>http://ma.gnolia.com/applications/new</URI>
- </Service>
- </XRD>
-
- <!-- Global Resource Definition -->
-
- <XRD xmlns="xri://$XRD*($v*2.0)" version="2.0">
- <Type>xri://$xrds*simple</Type>
-
- <!-- OAuth Endpoints Definition -->
- <Service priority="10">
- <Type>http://oauth.net/discovery/1.0</Type>
- <URI>#oauth</URI>
- </Service>
- </XRD>
-
-</XRDS> \ No newline at end of file
diff --git a/mod/oauth_api/vendors/oauth/test/oauth_test.php b/mod/oauth_api/vendors/oauth/test/oauth_test.php
deleted file mode 100644
index 0c0504c70..000000000
--- a/mod/oauth_api/vendors/oauth/test/oauth_test.php
+++ /dev/null
@@ -1,188 +0,0 @@
-<?php
-
-/**
- * Tests of OAuth implementation.
- *
- * @version $Id$
- * @author Marc Worrell <marcw@pobox.com>
- * @date Nov 29, 2007 3:46:56 PM
- * @see http://wiki.oauth.net/TestCases
- *
- * The MIT License
- *
- * Copyright (c) 2007-2008 Mediamatic Lab
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require_once dirname(__FILE__) . '/../library/OAuthRequest.php';
-require_once dirname(__FILE__) . '/../library/OAuthRequester.php';
-require_once dirname(__FILE__) . '/../library/OAuthRequestSigner.php';
-require_once dirname(__FILE__) . '/../library/OAuthRequestVerifier.php';
-
-if (!function_exists('getallheaders'))
-{
- function getallheaders()
- {
- return array();
- }
-}
-
-
-oauth_test();
-
-function oauth_test ()
-{
- error_reporting(E_ALL);
-
- header('Content-Type: text/plain; charset=utf-8');
-
- echo "Performing OAuth module tests.\n\n";
- echo "See also: http://wiki.oauth.net/TestCases\n\n";
-
- assert_options(ASSERT_CALLBACK, 'oauth_assert_handler');
- assert_options(ASSERT_WARNING, 0);
-
- $req = new OAuthRequest('http://www.example.com', 'GET');
-
- echo "***** Parameter Encoding *****\n\n";
-
- assert('$req->urlencode(\'abcABC123\') == \'abcABC123\'');
- assert('$req->urlencode(\'-._~\') == \'-._~\'');
- assert('$req->urlencode(\'%\') == \'%25\'');
- assert('$req->urlencode(\'&=*\') == \'%26%3D%2A\'');
- assert('$req->urlencode(\'&=*\') == \'%26%3D%2A\'');
- assert('$req->urlencode("\n") == \'%0A\'');
- assert('$req->urlencode(" ") == \'%20\'');
- assert('$req->urlencode("\x7f") == \'%7F\'');
-
-
- echo "***** Normalize Request Parameters *****\n\n";
-
- $req = new OAuthRequest('http://example.com/?name', 'GET');
- assert('$req->getNormalizedParams() == \'name=\'');
-
- $req = new OAuthRequest('http://example.com/?a=b', 'GET');
- assert('$req->getNormalizedParams() == \'a=b\'');
-
- $req = new OAuthRequest('http://example.com/?a=b&c=d', 'GET');
- assert('$req->getNormalizedParams() == \'a=b&c=d\'');
-
- // At this moment we don't support two parameters with the same name
- // so I changed this test case to "a=" and "b=" and not "a=" and "a="
- $req = new OAuthRequest('http://example.com/?b=x!y&a=x+y', 'GET');
- assert('$req->getNormalizedParams() == \'a=x%20y&b=x%21y\'');
-
- $req = new OAuthRequest('http://example.com/?x!y=a&x=a', 'GET');
- assert('$req->getNormalizedParams() == \'x=a&x%21y=a\'');
-
-
- echo "***** Base String *****\n\n";
-
- $req = new OAuthRequest('http://example.com/?n=v', 'GET');
- assert('$req->signatureBaseString() == \'GET&http%3A%2F%2Fexample.com%2F&n%3Dv\'');
-
- $req = new OAuthRequest(
- 'https://photos.example.net/request_token',
- 'POST',
- 'oauth_version=1.0&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_timestamp=1191242090&oauth_nonce=hsu94j3884jdopsl&oauth_signature_method=PLAINTEXT&oauth_signature=ignored',
- array('X-OAuth-Test' => true));
- assert('$req->signatureBaseString() == \'POST&https%3A%2F%2Fphotos.example.net%2Frequest_token&oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dhsu94j3884jdopsl%26oauth_signature_method%3DPLAINTEXT%26oauth_timestamp%3D1191242090%26oauth_version%3D1.0\'');
-
- $req = new OAuthRequest(
- 'http://photos.example.net/photos?file=vacation.jpg&size=original&oauth_version=1.0&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_token=nnch734d00sl2jdk&oauth_timestamp=1191242096&oauth_nonce=kllo9940pd9333jh&oauth_signature=ignored&oauth_signature_method=HMAC-SHA1',
- 'GET');
- assert('$req->signatureBaseString() == \'GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal\'');
-
-
- echo "***** HMAC-SHA1 *****\nRequest signing\n";
-
- OAuthStore::instance('MySQL', array('conn'=>false));
- $req = new OAuthRequestSigner('http://photos.example.net/photos?file=vacation.jpg&size=original', 'GET');
-
- assert('$req->urldecode($req->calculateDataSignature(\'bs\', \'cs\', \'\', \'HMAC-SHA1\')) == \'egQqG5AJep5sJ7anhXju1unge2I=\'');
- assert('$req->urldecode($req->calculateDataSignature(\'bs\', \'cs\', \'ts\', \'HMAC-SHA1\')) == \'VZVjXceV7JgPq/dOTnNmEfO0Fv8=\'');
-
- $secrets = array(
- 'consumer_key' => 'dpf43f3p2l4k3l03',
- 'consumer_secret' => 'kd94hf93k423kf44',
- 'token' => 'nnch734d00sl2jdk',
- 'token_secret' => 'pfkkdhi9sl3r4s00',
- 'signature_methods' => array('HMAC-SHA1'),
- 'nonce' => 'kllo9940pd9333jh',
- 'timestamp' => '1191242096'
- );
- $req->sign(0, $secrets);
- assert('$req->getParam(\'oauth_signature\', true) == \'tR3+Ty81lMeYAr/Fid0kMTYa/WM=\'');
-
- echo "***** HMAC-SHA1 *****\nRequest verification\n";
-
- $req = new OAuthRequestVerifier(
- 'http://photos.example.net/photos?file=vacation.jpg&size=original'
- .'&oauth_consumer_key=dpf43f3p2l4k3l03&oauth_token=nnch734d00sl2jdk'
- .'&oauth_signature_method=HMAC-SHA1&oauth_nonce=kllo9940pd9333jh'
- .'&oauth_timestamp=1191242096&oauth_version=1.0'
- .'&oauth_signature='.rawurlencode('tR3+Ty81lMeYAr/Fid0kMTYa/WM=')
- , 'GET');
-
- $req->verifySignature('kd94hf93k423kf44', 'pfkkdhi9sl3r4s00');
-
- echo "\n";
- echo "***** Yahoo! test case ******\n\n";
-
- OAuthStore::instance('MySQL', array('conn'=>false));
- $req = new OAuthRequestSigner('http://example.com:80/photo', 'GET');
-
- $req->setParam('title', 'taken with a 30% orange filter');
- $req->setParam('file', 'mountain & water view');
- $req->setParam('format', 'jpeg');
- $req->setParam('include', array('date','aperture'));
-
- $secrets = array(
- 'consumer_key' => '1234=asdf=4567',
- 'consumer_secret' => 'erks823*43=asd&123ls%23',
- 'token' => 'asdf-4354=asew-5698',
- 'token_secret' => 'dis9$#$Js009%==',
- 'signature_methods' => array('HMAC-SHA1'),
- 'nonce' => '3jd834jd9',
- 'timestamp' => '12303202302'
- );
- $req->sign(0, $secrets);
-
- // echo "Basestring:\n",$req->signatureBaseString(), "\n\n";
-
- //echo "queryString:\n",$req->getQueryString(), "\n\n";
- assert('$req->getQueryString() == \'title=taken%20with%20a%2030%25%20orange%20filter&file=mountain%20%26%20water%20view&format=jpeg&include=date&include=aperture\'');
-
- //echo "oauth_signature:\n",$req->getParam('oauth_signature', true),"\n\n";
- assert('$req->getParam(\'oauth_signature\', true) == \'jMdUSR1vOr3SzNv3gZ5DDDuGirA=\'');
-
- echo "\n\nFinished.\n";
-}
-
-
-function oauth_assert_handler ( $file, $line, $code )
-{
- echo "\nAssertion failed in $file:$line
- $code\n\n";
-}
-
-/* vi:set ts=4 sts=4 sw=4 binary noeol: */
-
-?> \ No newline at end of file
diff --git a/mod/pages/actions/annotations/page/delete.php b/mod/pages/actions/annotations/page/delete.php
new file mode 100644
index 000000000..156b516d2
--- /dev/null
+++ b/mod/pages/actions/annotations/page/delete.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Remove a page (revision) annotation
+ *
+ * @package ElggPages
+ */
+
+// Make sure we can get the annotations and entity in question
+$annotation_id = (int) get_input('annotation_id');
+$annotation = elgg_get_annotation_from_id($annotation_id);
+$entity = get_entity($annotation->entity_guid);
+
+if ($annotation && $entity->canEdit() && $annotation->canEdit()) {
+ $annotation->delete();
+ system_message(elgg_echo("pages:revision:delete:success"));
+} else {
+ register_error(elgg_echo("pages:revision:delete:failure"));
+}
+
+forward("pages/history/{$annotation->entity_guid}"); \ No newline at end of file
diff --git a/mod/pages/actions/pages/delete.php b/mod/pages/actions/pages/delete.php
index 7a314a280..fd5791e4d 100644
--- a/mod/pages/actions/pages/delete.php
+++ b/mod/pages/actions/pages/delete.php
@@ -21,11 +21,33 @@ if (elgg_instanceof($page, 'object', 'page') || elgg_instanceof($page, 'object',
'metadata_value' => $page->getGUID()
));
if ($children) {
+ $db_prefix = elgg_get_config('dbprefix');
+ $subtype_id = (int)get_subtype_id('object', 'page_top');
+ $newentity_cache = is_memcache_available() ? new ElggMemcache('new_entity_cache') : null;
+
foreach ($children as $child) {
- $child->parent_guid = $parent;
+ if ($parent) {
+ $child->parent_guid = $parent;
+ } else {
+ // If no parent, we need to transform $child to a page_top
+ $child_guid = (int)$child->guid;
+
+ update_data("UPDATE {$db_prefix}entities
+ SET subtype = $subtype_id WHERE guid = $child_guid");
+
+ elgg_delete_metadata(array(
+ 'guid' => $child_guid,
+ 'metadata_name' => 'parent_guid',
+ ));
+
+ _elgg_invalidate_cache_for_entity($child_guid);
+ if ($newentity_cache) {
+ $newentity_cache->delete($child_guid);
+ }
+ }
}
}
-
+
if ($page->delete()) {
system_message(elgg_echo('pages:delete:success'));
if ($parent) {
diff --git a/mod/pages/languages/en.php b/mod/pages/languages/en.php
index 930676b3e..c204c1901 100644
--- a/mod/pages/languages/en.php
+++ b/mod/pages/languages/en.php
@@ -15,7 +15,7 @@ $english = array(
'pages:owner' => "%s's pages",
'pages:friends' => "Friends' pages",
'pages:all' => "All site pages",
- 'pages:add' => "Add page",
+ 'pages:add' => "Add a page",
'pages:group' => "Group pages",
'groups:enablepages' => 'Enable group pages',
@@ -25,6 +25,8 @@ $english = array(
'pages:history' => "History",
'pages:view' => "View page",
'pages:revision' => "Revision",
+ 'pages:current_revision' => "Current Revision",
+ 'pages:revert' => "Revert",
'pages:navigation' => "Navigation",
'pages:new' => "A new page",
@@ -75,6 +77,9 @@ View and comment on the new page:
'pages:error:no_title' => 'You must specify a title for this page.',
'pages:delete:success' => 'The page was successfully deleted.',
'pages:delete:failure' => 'The page could not be deleted.',
+ 'pages:revision:delete:success' => 'The page revision was successfully deleted.',
+ 'pages:revision:delete:failure' => 'The page revision could not be deleted.',
+ 'pages:revision:not_found' => 'Cannot find this revision.',
/**
* Page
diff --git a/mod/pages/lib/pages.php b/mod/pages/lib/pages.php
index afe42b68f..7f90d53d8 100644
--- a/mod/pages/lib/pages.php
+++ b/mod/pages/lib/pages.php
@@ -9,7 +9,7 @@
* @param ElggObject $page
* @return array
*/
-function pages_prepare_form_vars($page = null, $parent_guid = 0) {
+function pages_prepare_form_vars($page = null, $parent_guid = 0, $revision = null) {
// input names => defaults
$values = array(
@@ -41,6 +41,11 @@ function pages_prepare_form_vars($page = null, $parent_guid = 0) {
elgg_clear_sticky_form('page');
+ // load the revision annotation if requested
+ if ($revision instanceof ElggAnnotation && $revision->entity_guid == $page->getGUID()) {
+ $values['description'] = $revision->value;
+ }
+
return $values;
}
diff --git a/mod/pages/pages/pages/edit.php b/mod/pages/pages/pages/edit.php
index 1f411b94d..a925cdc55 100644
--- a/mod/pages/pages/pages/edit.php
+++ b/mod/pages/pages/pages/edit.php
@@ -8,6 +8,7 @@
gatekeeper();
$page_guid = (int)get_input('guid');
+$revision = (int)get_input('annotation_id');
$page = get_entity($page_guid);
if (!$page) {
register_error(elgg_echo('noaccess'));
@@ -28,7 +29,17 @@ elgg_push_breadcrumb(elgg_echo('edit'));
$title = elgg_echo("pages:edit");
if ($page->canEdit()) {
- $vars = pages_prepare_form_vars($page);
+
+ if ($revision) {
+ $revision = elgg_get_annotation_from_id($revision);
+ if (!$revision || !($revision->entity_guid == $page_guid)) {
+ register_error(elgg_echo('pages:revision:not_found'));
+ forward(REFERER);
+ }
+ }
+
+ $vars = pages_prepare_form_vars($page, $page->parent_guid, $revision);
+
$content = elgg_view_form('pages/edit', array(), $vars);
} else {
$content = elgg_echo("pages:noaccess");
diff --git a/mod/pages/pages/pages/friends.php b/mod/pages/pages/pages/friends.php
index 87ac631c2..cecc4053b 100644
--- a/mod/pages/pages/pages/friends.php
+++ b/mod/pages/pages/pages/friends.php
@@ -7,7 +7,7 @@
$owner = elgg_get_page_owner_entity();
if (!$owner) {
- forward('pages/all');
+ forward('', '404');
}
elgg_push_breadcrumb($owner->name, "pages/owner/$owner->username");
diff --git a/mod/pages/pages/pages/history.php b/mod/pages/pages/pages/history.php
index 872596179..7f5fa4f4f 100644
--- a/mod/pages/pages/pages/history.php
+++ b/mod/pages/pages/pages/history.php
@@ -9,12 +9,12 @@ $page_guid = get_input('guid');
$page = get_entity($page_guid);
if (!$page) {
-
+ forward('', '404');
}
$container = $page->getContainerEntity();
if (!$container) {
-
+ forward('', '404');
}
elgg_set_page_owner_guid($container->getGUID());
diff --git a/mod/pages/pages/pages/owner.php b/mod/pages/pages/pages/owner.php
index 48199368c..7de74a3b4 100644
--- a/mod/pages/pages/pages/owner.php
+++ b/mod/pages/pages/pages/owner.php
@@ -7,7 +7,7 @@
$owner = elgg_get_page_owner_entity();
if (!$owner) {
- forward('pages/all');
+ forward('', '404');
}
// access check for closed groups
diff --git a/mod/pages/start.php b/mod/pages/start.php
index 6d974f122..f9c34cd85 100644
--- a/mod/pages/start.php
+++ b/mod/pages/start.php
@@ -28,9 +28,10 @@ function pages_init() {
elgg_register_annotation_url_handler('page', 'pages_revision_url');
// Register some actions
- $action_base = elgg_get_plugins_path() . 'pages/actions/pages';
- elgg_register_action("pages/edit", "$action_base/edit.php");
- elgg_register_action("pages/delete", "$action_base/delete.php");
+ $action_base = elgg_get_plugins_path() . 'pages/actions';
+ elgg_register_action("pages/edit", "$action_base/pages/edit.php");
+ elgg_register_action("pages/delete", "$action_base/pages/delete.php");
+ elgg_register_action("annotations/page/delete", "$action_base/annotations/page/delete.php");
// Extend the main css view
elgg_extend_view('css/elgg', 'pages/css');
@@ -80,8 +81,13 @@ function pages_init() {
// entity menu
elgg_register_plugin_hook_handler('register', 'menu:entity', 'pages_entity_menu_setup');
+ // hook into annotation menu
+ elgg_register_plugin_hook_handler('register', 'menu:annotation', 'pages_annotation_menu_setup');
+
// register ecml views to parse
elgg_register_plugin_hook_handler('get_views', 'ecml', 'pages_ecml_views_hook');
+
+ elgg_register_event_handler('upgrade', 'system', 'pages_run_upgrades');
}
/**
@@ -281,25 +287,37 @@ function page_notify_message($hook, $entity_type, $returnvalue, $params) {
/**
* Extend permissions checking to extend can-edit for write users.
*
- * @param unknown_type $hook
- * @param unknown_type $entity_type
- * @param unknown_type $returnvalue
- * @param unknown_type $params
+ * @param string $hook
+ * @param string $entity_type
+ * @param bool $returnvalue
+ * @param array $params
*/
-function pages_write_permission_check($hook, $entity_type, $returnvalue, $params)
-{
+function pages_write_permission_check($hook, $entity_type, $returnvalue, $params) {
if ($params['entity']->getSubtype() == 'page'
|| $params['entity']->getSubtype() == 'page_top') {
$write_permission = $params['entity']->write_access_id;
$user = $params['user'];
- if (($write_permission) && ($user)) {
- // $list = get_write_access_array($user->guid);
- $list = get_access_array($user->guid); // get_access_list($user->guid);
-
- if (($write_permission!=0) && (in_array($write_permission,$list))) {
- return true;
+ if ($write_permission && $user) {
+ switch ($write_permission) {
+ case ACCESS_PRIVATE:
+ // Elgg's default decision is what we want
+ return;
+ break;
+ case ACCESS_FRIENDS:
+ $owner = $params['entity']->getOwnerEntity();
+ if ($owner && $owner->isFriendsWith($user->guid)) {
+ return true;
+ }
+ break;
+ default:
+ $list = get_access_array($user->guid);
+ if (in_array($write_permission, $list)) {
+ // user in the access collection
+ return true;
+ }
+ break;
}
}
}
diff --git a/mod/pages/upgrades/2012061800.php b/mod/pages/upgrades/2012061800.php
new file mode 100644
index 000000000..c21ccae3b
--- /dev/null
+++ b/mod/pages/upgrades/2012061800.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Restore disappeared subpages. This is caused by its parent page being deleted
+ * when the parent page is a top level page. We take advantage of the fact that
+ * the parent_guid was deleted for the subpages.
+ *
+ * This upgrade script will no longer work once we have converted all pages to
+ * have the same entity subtype.
+ */
+
+
+/**
+ * Update subtype
+ *
+ * @param ElggObject $page
+ */
+function pages_2012061800($page) {
+ $dbprefix = elgg_get_config('dbprefix');
+ $subtype_id = (int)get_subtype_id('object', 'page_top');
+ $page_guid = (int)$page->guid;
+ update_data("UPDATE {$dbprefix}entities
+ SET subtype = $subtype_id WHERE guid = $page_guid");
+ error_log("called");
+ return true;
+}
+
+$previous_access = elgg_set_ignore_access(true);
+
+$dbprefix = elgg_get_config('dbprefix');
+$name_metastring_id = get_metastring_id('parent_guid');
+if (!$name_metastring_id) {
+ return;
+}
+
+// Looking for pages without metadata
+$options = array(
+ 'type' => 'object',
+ 'subtype' => 'page',
+ 'wheres' => "NOT EXISTS (
+ SELECT 1 FROM {$dbprefix}metadata md
+ WHERE md.entity_guid = e.guid
+ AND md.name_id = $name_metastring_id)"
+);
+$batch = new ElggBatch('elgg_get_entities_from_metadata', $options, 'pages_2012061800', 50, false);
+elgg_set_ignore_access($previous_access);
+
+if ($batch->callbackResult) {
+ error_log("Elgg Pages upgrade (2012061800) succeeded");
+}
diff --git a/mod/pages/views/default/annotation/page.php b/mod/pages/views/default/annotation/page.php
index a621b9281..ecb289092 100644
--- a/mod/pages/views/default/annotation/page.php
+++ b/mod/pages/views/default/annotation/page.php
@@ -39,4 +39,22 @@ $body = <<< HTML
<p class="elgg-subtext">$subtitle</p>
HTML;
+if (!elgg_in_context('widgets')) {
+ $menu = elgg_view_menu('annotation', array(
+ 'annotation' => $annotation,
+ 'sort_by' => 'priority',
+ 'class' => 'elgg-menu-hz float-alt',
+ ));
+}
+
+$body = <<<HTML
+<div class="mbn">
+ $menu
+ <h3>$title_link</h3>
+ <span class="elgg-subtext">
+ $subtitle
+ </span>
+</div>
+HTML;
+
echo elgg_view_image_block($icon, $body); \ No newline at end of file
diff --git a/mod/pages/views/default/object/page_top.php b/mod/pages/views/default/object/page_top.php
index 945a22eed..f35202993 100644
--- a/mod/pages/views/default/object/page_top.php
+++ b/mod/pages/views/default/object/page_top.php
@@ -60,18 +60,26 @@ if ($comments_count != 0 && !$revision) {
$comments_link = '';
}
-$metadata = elgg_view_menu('entity', array(
- 'entity' => $vars['entity'],
- 'handler' => 'pages',
- 'sort_by' => 'priority',
- 'class' => 'elgg-menu-hz',
-));
-
$subtitle = "$editor_text $comments_link $categories";
// do not show the metadata and controls in widget view
-if (elgg_in_context('widgets') || $revision) {
- $metadata = '';
+if (!elgg_in_context('widgets')) {
+ // If we're looking at a revision, display annotation menu
+ if ($revision) {
+ $metadata = elgg_view_menu('annotation', array(
+ 'annotation' => $annotation,
+ 'sort_by' => 'priority',
+ 'class' => 'elgg-menu-hz float-alt',
+ ));
+ } else {
+ // Regular entity menu
+ $metadata = elgg_view_menu('entity', array(
+ 'entity' => $vars['entity'],
+ 'handler' => 'pages',
+ 'sort_by' => 'priority',
+ 'class' => 'elgg-menu-hz',
+ ));
+ }
}
if ($full) {
diff --git a/mod/pages/views/default/pages/sidebar/history.php b/mod/pages/views/default/pages/sidebar/history.php
index 7077edb9a..e0e8ed11a 100644
--- a/mod/pages/views/default/pages/sidebar/history.php
+++ b/mod/pages/views/default/pages/sidebar/history.php
@@ -14,6 +14,7 @@ if ($vars['page']) {
'limit' => 20,
'reverse_order_by' => true
);
+ elgg_push_context('widgets');
$content = elgg_list_annotations($options);
}
diff --git a/mod/profile/icondirect.php b/mod/profile/icondirect.php
index dbab5d31f..5f1599e0d 100644
--- a/mod/profile/icondirect.php
+++ b/mod/profile/icondirect.php
@@ -55,13 +55,13 @@ if ($mysql_dblink) {
$user_path = date('Y/m/d/', $join_date) . $guid;
$filename = "$data_root$user_path/profile/{$guid}{$size}.jpg";
- $size = @filesize($filename);
- if ($size) {
+ $filesize = @filesize($filename);
+ if ($filesize) {
header("Content-type: image/jpeg");
header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', strtotime("+6 months")), true);
header("Pragma: public");
header("Cache-Control: public");
- header("Content-Length: $size");
+ header("Content-Length: $filesize");
header("ETag: \"$etag\"");
readfile($filename);
exit;
diff --git a/mod/profile/views/default/profile/details.php b/mod/profile/views/default/profile/details.php
index 7b05b0e15..da4e95690 100644
--- a/mod/profile/views/default/profile/details.php
+++ b/mod/profile/views/default/profile/details.php
@@ -21,8 +21,22 @@ if (is_array($profile_fields) && sizeof($profile_fields) > 0) {
continue;
}
$value = $user->$shortname;
+
if (!empty($value)) {
- //This function controls the alternating class
+
+ // fix profile URLs populated by https://github.com/Elgg/Elgg/issues/5232
+ // @todo Replace with upgrade script, only need to alter users with last_update after 1.8.13
+ if ($valtype == 'url' && $value == 'http://') {
+ $user->$shortname = '';
+ continue;
+ }
+
+ // validate urls
+ if ($valtype == 'url' && !preg_match('~^https?\://~i', $value)) {
+ $value = "http://$value";
+ }
+
+ // this controls the alternating class
$even_odd = ( 'odd' != $even_odd ) ? 'odd' : 'even';
?>
<div class="<?php echo $even_odd; ?>">
diff --git a/mod/reportedcontent/views/default/object/reported_content.php b/mod/reportedcontent/views/default/object/reported_content.php
index 0e733e154..cc33f54fb 100644
--- a/mod/reportedcontent/views/default/object/reported_content.php
+++ b/mod/reportedcontent/views/default/object/reported_content.php
@@ -57,16 +57,6 @@ if ($report->state == 'archived') {
<p>
<b><?php echo elgg_echo('reportedcontent:objecttitle'); ?>:</b>
<?php echo $report->title; ?>
- <br />
- <?php echo elgg_view('output/url', array(
- 'href' => "#report-$report->guid",
- 'text' => elgg_echo('reportedcontent:moreinfo'),
- 'rel' => "toggle",
- ));
- ?>
- </p>
- </div>
- <div class="report-details hidden" id="report-<?php echo $report->getGUID();?>">
<p>
<b><?php echo elgg_echo('reportedcontent:objecturl'); ?>:</b>
<?php echo elgg_view('output/url', array(
@@ -77,6 +67,16 @@ if ($report->state == 'archived') {
?>
</p>
<p>
+ <?php echo elgg_view('output/url', array(
+ 'href' => "#report-$report->guid",
+ 'text' => elgg_echo('reportedcontent:moreinfo'),
+ 'rel' => "toggle",
+ ));
+ ?>
+ </p>
+ </div>
+ <div class="report-details hidden" id="report-<?php echo $report->getGUID();?>">
+ <p>
<b><?php echo elgg_echo('reportedcontent:reason'); ?>:</b>
<?php echo $report->description; ?>
</p>
diff --git a/mod/search/README.txt b/mod/search/README.txt
index 98a002dd5..ac5930e5f 100644
--- a/mod/search/README.txt
+++ b/mod/search/README.txt
@@ -273,4 +273,4 @@ MySQL's fulltext engine returns *ZERO* rows if more than 50% of
the rows searched match.
The default search hooks for users and groups ignore subtypes.
-See [trac ticket 1499](http://trac.elgg.org/elgg/ticket/1499)
+See [GitHub issue 1499](https://github.com/elgg/elgg/issues/1499)
diff --git a/mod/search/search_hooks.php b/mod/search/search_hooks.php
index 47351fb8a..923cf0aa8 100644
--- a/mod/search/search_hooks.php
+++ b/mod/search/search_hooks.php
@@ -3,17 +3,17 @@
* Elgg core search.
*
* @package Elgg
- * @subpackage Core
+ * @subpackage Search
*/
/**
- * Return default results for searches on objects.
+ * Get objects that match the search parameters.
*
- * @param unknown_type $hook
- * @param unknown_type $type
- * @param unknown_type $value
- * @param unknown_type $params
- * @return unknown_type
+ * @param string $hook Hook name
+ * @param string $type Hook type
+ * @param array $value Empty array
+ * @param array $params Search parameters
+ * @return array
*/
function search_objects_hook($hook, $type, $value, $params) {
@@ -23,7 +23,7 @@ function search_objects_hook($hook, $type, $value, $params) {
$params['joins'] = array($join);
$fields = array('title', 'description');
- $where = search_get_where_sql('oe', $fields, $params, FALSE);
+ $where = search_get_where_sql('oe', $fields, $params);
$params['wheres'] = array($where);
$params['count'] = TRUE;
@@ -54,13 +54,13 @@ function search_objects_hook($hook, $type, $value, $params) {
}
/**
- * Return default results for searches on groups.
+ * Get groups that match the search parameters.
*
- * @param unknown_type $hook
- * @param unknown_type $type
- * @param unknown_type $value
- * @param unknown_type $params
- * @return unknown_type
+ * @param string $hook Hook name
+ * @param string $type Hook type
+ * @param array $value Empty array
+ * @param array $params Search parameters
+ * @return array
*/
function search_groups_hook($hook, $type, $value, $params) {
$db_prefix = elgg_get_config('dbprefix');
@@ -69,12 +69,9 @@ function search_groups_hook($hook, $type, $value, $params) {
$join = "JOIN {$db_prefix}groups_entity ge ON e.guid = ge.guid";
$params['joins'] = array($join);
-
$fields = array('name', 'description');
- // force into boolean mode because we've having problems with the
- // "if > 50% match 0 sets are returns" problem.
- $where = search_get_where_sql('ge', $fields, $params, FALSE);
+ $where = search_get_where_sql('ge', $fields, $params);
$params['wheres'] = array($where);
@@ -109,15 +106,15 @@ function search_groups_hook($hook, $type, $value, $params) {
}
/**
- * Return default results for searches on users.
- *
- * @todo add profile field MD searching
+ * Get users that match the search parameters.
*
- * @param unknown_type $hook
- * @param unknown_type $type
- * @param unknown_type $value
- * @param unknown_type $params
- * @return unknown_type
+ * Searches on username, display name, and profile fields
+ *
+ * @param string $hook Hook name
+ * @param string $type Hook type
+ * @param array $value Empty array
+ * @param array $params Search parameters
+ * @return array
*/
function search_users_hook($hook, $type, $value, $params) {
$db_prefix = elgg_get_config('dbprefix');
@@ -178,11 +175,20 @@ function search_users_hook($hook, $type, $value, $params) {
$entity->setVolatileData('search_matched_title', $title);
$matched = '';
- foreach ($profile_fields as $md) {
- $text = $entity->$md;
- if (stristr($text, $query)) {
- $matched .= elgg_echo("profile:{$md}") . ': '
- . search_get_highlighted_relevant_substrings($text, $query);
+ foreach ($profile_fields as $md_name) {
+ $metadata = $entity->$md_name;
+ if (is_array($metadata)) {
+ foreach ($metadata as $text) {
+ if (stristr($text, $query)) {
+ $matched .= elgg_echo("profile:{$md_name}") . ': '
+ . search_get_highlighted_relevant_substrings($text, $query);
+ }
+ }
+ } else {
+ if (stristr($metadata, $query)) {
+ $matched .= elgg_echo("profile:{$md_name}") . ': '
+ . search_get_highlighted_relevant_substrings($metadata, $query);
+ }
}
}
@@ -196,13 +202,13 @@ function search_users_hook($hook, $type, $value, $params) {
}
/**
- * Return default results for searches on tags.
+ * Get entities with tags that match the search parameters.
*
- * @param unknown_type $hook
- * @param unknown_type $type
- * @param unknown_type $value
- * @param unknown_type $params
- * @return unknown_type
+ * @param string $hook Hook name
+ * @param string $type Hook type
+ * @param array $value Empty array
+ * @param array $params Search parameters
+ * @return array
*/
function search_tags_hook($hook, $type, $value, $params) {
$db_prefix = elgg_get_config('dbprefix');
@@ -331,11 +337,11 @@ function search_tags_hook($hook, $type, $value, $params) {
/**
* Register tags as a custom search type.
*
- * @param unknown_type $hook
- * @param unknown_type $type
- * @param unknown_type $value
- * @param unknown_type $params
- * @return unknown_type
+ * @param string $hook Hook name
+ * @param string $type Hook type
+ * @param array $value Array of custom search types
+ * @param array $params Search parameters
+ * @return array
*/
function search_custom_types_tags_hook($hook, $type, $value, $params) {
$value[] = 'tags';
@@ -344,13 +350,13 @@ function search_custom_types_tags_hook($hook, $type, $value, $params) {
/**
- * Return default results for searches on comments.
+ * Get comments that match the search parameters.
*
- * @param unknown_type $hook
- * @param unknown_type $type
- * @param unknown_type $value
- * @param unknown_type $params
- * @return unknown_type
+ * @param string $hook Hook name
+ * @param string $type Hook type
+ * @param array $value Empty array
+ * @param array $params Search parameters
+ * @return array
*/
function search_comments_hook($hook, $type, $value, $params) {
$db_prefix = elgg_get_config('dbprefix');
@@ -399,14 +405,19 @@ function search_comments_hook($hook, $type, $value, $params) {
// don't continue if nothing there...
if (!$count) {
- return array ('entities' => array(), 'count' => 0);
+ return array('entities' => array(), 'count' => 0);
}
-
- $order_by = search_get_order_by_sql('e', null, $params['sort'], $params['order']);
+
+ // no full text index on metastrings table
+ if ($params['sort'] == 'relevance') {
+ $params['sort'] = 'created';
+ }
+
+ $order_by = search_get_order_by_sql('a', null, $params['sort'], $params['order']);
if ($order_by) {
$order_by = "ORDER BY $order_by";
}
-
+
$q = "SELECT DISTINCT a.*, msv.string as comment FROM {$db_prefix}annotations a
JOIN {$db_prefix}metastrings msn ON a.name_id = msn.id
JOIN {$db_prefix}metastrings msv ON a.value_id = msv.id
@@ -444,10 +455,17 @@ function search_comments_hook($hook, $type, $value, $params) {
}
$comment_str = search_get_highlighted_relevant_substrings($comment->comment, $query);
- $entity->setVolatileData('search_match_annotation_id', $comment->id);
- $entity->setVolatileData('search_matched_comment', $comment_str);
- $entity->setVolatileData('search_matched_comment_owner_guid', $comment->owner_guid);
- $entity->setVolatileData('search_matched_comment_time_created', $comment->time_created);
+ $comments_data = $entity->getVolatileData('search_comments_data');
+ if (!$comments_data) {
+ $comments_data = array();
+ }
+ $comments_data[] = array(
+ 'annotation_id' => $comment->id,
+ 'text' => $comment_str,
+ 'owner_guid' => $comment->owner_guid,
+ 'time_created' => $comment->time_created,
+ );
+ $entity->setVolatileData('search_comments_data', $comments_data);
$entities[] = $entity;
}
@@ -460,11 +478,11 @@ function search_comments_hook($hook, $type, $value, $params) {
/**
* Register comments as a custom search type.
*
- * @param unknown_type $hook
- * @param unknown_type $type
- * @param unknown_type $value
- * @param unknown_type $params
- * @return unknown_type
+ * @param string $hook Hook name
+ * @param string $type Hook type
+ * @param array $value Array of custom search types
+ * @param array $params Search parameters
+ * @return array
*/
function search_custom_types_comments_hook($hook, $type, $value, $params) {
$value[] = 'comments';
diff --git a/mod/search/views/default/search/comments/entity.php b/mod/search/views/default/search/comments/entity.php
index 005bb270c..77e950843 100644
--- a/mod/search/views/default/search/comments/entity.php
+++ b/mod/search/views/default/search/comments/entity.php
@@ -6,8 +6,11 @@
*/
$entity = $vars['entity'];
+$comments_data = $entity->getVolatileData('search_comments_data');
+$comment_data = array_shift($comments_data);
+$entity->setVolatileData('search_comments_data', $comments_data);
-$owner = get_entity($entity->getVolatileData('search_matched_comment_owner_guid'));
+$owner = get_entity($comment_data['owner_guid']);
if ($owner instanceof ElggUser) {
$icon = elgg_view_entity_icon($owner, 'tiny');
@@ -38,12 +41,12 @@ if ($entity->getVolatileData('search_unavailable_entity')) {
$title = elgg_echo('search:comment_on', array($title));
// @todo this should use something like $comment->getURL()
- $url = $entity->getURL() . '#comment_' . $entity->getVolatileData('search_match_annotation_id');
+ $url = $entity->getURL() . '#comment_' . $comment_data['annotation_id'];
$title = "<a href=\"$url\">$title</a>";
}
-$description = $entity->getVolatileData('search_matched_comment');
-$tc = $entity->getVolatileData('search_matched_comment_time_created');;
+$description = $comment_data['text'];
+$tc = $comment_data['time_created'];
$time = elgg_view_friendly_time($tc);
$body = "<p class=\"mbn\">$title</p>$description";
diff --git a/mod/search/views/default/search/list.php b/mod/search/views/default/search/list.php
index 1ed40be1b..90aa28989 100644
--- a/mod/search/views/default/search/list.php
+++ b/mod/search/views/default/search/list.php
@@ -36,16 +36,21 @@ $query = http_build_query(
$url = elgg_get_site_url() . "search?$query";
+$more_items = $vars['results']['count'] - ($vars['params']['offset'] + $vars['params']['limit']);
+
// get pagination
if (array_key_exists('pagination', $vars['params']) && $vars['params']['pagination']) {
- $nav = elgg_view('navigation/pagination',array(
+ $nav = elgg_view('navigation/pagination', array(
'base_url' => $url,
'offset' => $vars['params']['offset'],
'count' => $vars['results']['count'],
'limit' => $vars['params']['limit'],
));
+ $show_more = false;
} else {
+ // faceted search page so no pagination
$nav = '';
+ $show_more = $more_items > 0;
}
// figure out what we're dealing with.
@@ -75,12 +80,7 @@ if (array_key_exists('search_type', $vars['params'])
$type_str = $search_type_str;
}
-// get any more links.
-$more_check = $vars['results']['count'] - ($vars['params']['offset'] + $vars['params']['limit']);
-$more = ($more_check > 0) ? $more_check : 0;
-
-if ($more) {
- $title_key = ($more == 1) ? 'comment' : 'comments';
+if ($show_more) {
$more_str = elgg_echo('search:more', array($count, $type_str));
$more_url = elgg_http_remove_url_query_element($url, 'limit');
$more_link = "<li class='elgg-item'><a href=\"$more_url\">$more_str</a></li>";
diff --git a/mod/search/views/rss/search/comments/entity.php b/mod/search/views/rss/search/comments/entity.php
index 869779f35..e47afec4a 100644
--- a/mod/search/views/rss/search/comments/entity.php
+++ b/mod/search/views/rss/search/comments/entity.php
@@ -6,9 +6,12 @@
*/
$entity = $vars['entity'];
+$comments_data = $entity->getVolatileData('search_comments_data');
+$comment_data = array_shift($comments_data);
+$entity->setVolatileData('search_comments_data', $comments_data);
$author_name = '';
-$comment_author_guid = $entity->getVolatileData('search_matched_comment_owner_guid');
+$comment_author_guid = $comment_data['owner_guid'];
$author = get_user($comment_author_guid);
if ($author) {
$author_name = $author->name;
@@ -34,11 +37,11 @@ if ($entity->getVolatileData('search_unavailable_entity')) {
$title = elgg_echo('search:comment_on', array($title));
$title .= ' ' . elgg_echo('search:comment_by') . ' ' . $author_name;
- $url = $entity->getURL() . '#annotation-' . $entity->getVolatileData('search_match_annotation_id');
+ $url = $entity->getURL() . '#annotation-' . $comment_data['annotation_id'];
}
-$description = $entity->getVolatileData('search_matched_comment');
-$tc = $entity->getVolatileData('search_matched_comment_time_created');;
+$description = $comment_data['text'];
+$tc = $comment_data['time_created'];
?>
diff --git a/mod/thewire/pages/thewire/everyone.php b/mod/thewire/pages/thewire/everyone.php
index 909f0caf2..c7438747e 100644
--- a/mod/thewire/pages/thewire/everyone.php
+++ b/mod/thewire/pages/thewire/everyone.php
@@ -18,7 +18,7 @@ if (elgg_is_logged_in()) {
$content .= elgg_list_entities(array(
'type' => 'object',
'subtype' => 'thewire',
- 'limit' => 15,
+ 'limit' => get_input('limit', 15),
));
$body = elgg_view_layout('content', array(
diff --git a/mod/thewire/pages/thewire/friends.php b/mod/thewire/pages/thewire/friends.php
index e7f5eed59..efa7e7a56 100644
--- a/mod/thewire/pages/thewire/friends.php
+++ b/mod/thewire/pages/thewire/friends.php
@@ -5,7 +5,7 @@
$owner = elgg_get_page_owner_entity();
if (!$owner) {
- forward('thewire/all');
+ forward('', '404');
}
$title = elgg_echo('thewire:friends');
diff --git a/mod/thewire/pages/thewire/owner.php b/mod/thewire/pages/thewire/owner.php
index 6246c1770..dc25940e1 100644
--- a/mod/thewire/pages/thewire/owner.php
+++ b/mod/thewire/pages/thewire/owner.php
@@ -6,7 +6,7 @@
$owner = elgg_get_page_owner_entity();
if (!$owner) {
- forward('thewire/all');
+ forward('', '404');
}
$title = elgg_echo('thewire:user', array($owner->name));
@@ -26,7 +26,7 @@ $content .= elgg_list_entities(array(
'type' => 'object',
'subtype' => 'thewire',
'owner_guid' => $owner->guid,
- 'limit' => 15,
+ 'limit' => get_input('limit', 15),
));
$body = elgg_view_layout('content', array(
diff --git a/mod/tinymce/views/default/js/tinymce.php b/mod/tinymce/views/default/js/tinymce.php
index b4db43cee..344d71b14 100644
--- a/mod/tinymce/views/default/js/tinymce.php
+++ b/mod/tinymce/views/default/js/tinymce.php
@@ -66,6 +66,18 @@ elgg.tinymce.init = function() {
var text = elgg.echo('tinymce:word_count') + strip.split(' ').length + ' ';
tinymce.DOM.setHTML(tinymce.DOM.get(tinyMCE.activeEditor.id + '_path_row'), text);
});
+
+ ed.onInit.add(function(ed) {
+ // prevent Firefox from dragging/dropping files into editor
+ if (tinymce.isGecko) {
+ tinymce.dom.Event.add(ed.getBody().parentNode, "drop", function(e) {
+ if (e.dataTransfer.files.length > 0) {
+ e.preventDefault();
+ }
+ });
+ }
+ });
+
},
content_css: elgg.config.wwwroot + 'mod/tinymce/css/elgg_tinymce.css'
});
diff --git a/mod/twitter/graphics/thewire_speech_bubble.gif b/mod/twitter/graphics/thewire_speech_bubble.gif
deleted file mode 100644
index d0e8606a1..000000000
--- a/mod/twitter/graphics/thewire_speech_bubble.gif
+++ /dev/null
Binary files differ
diff --git a/mod/twitter/graphics/twitter16px.png b/mod/twitter/graphics/twitter16px.png
deleted file mode 100644
index de51c6953..000000000
--- a/mod/twitter/graphics/twitter16px.png
+++ /dev/null
Binary files differ
diff --git a/mod/twitter/languages/en.php b/mod/twitter/languages/en.php
deleted file mode 100644
index 11e745ba1..000000000
--- a/mod/twitter/languages/en.php
+++ /dev/null
@@ -1,17 +0,0 @@
-<?php
-/**
- * Twitter widget language file
- */
-
-$english = array(
- 'twitter:title' => 'Twitter',
- 'twitter:info' => 'Display your latest tweets',
- 'twitter:username' => 'Your twitter username',
- 'twitter:num' => 'Number of tweets to show*',
- 'twitter:visit' => 'visit my twitter',
- 'twitter:notset' => 'This widget needs to be configured. To display your latest tweets, click the customize icon and fill in your Twitter username.',
- 'twitter:invalid' => 'This widget is configured with an invalid Twitter username. Click the customize icon to correct it.',
- 'twitter:apibug' => "*Due to a bug in the Twitter 1.0 API, you may see fewer tweets than you ask for.",
-);
-
-add_translation("en", $english);
diff --git a/mod/twitter/manifest.xml b/mod/twitter/manifest.xml
deleted file mode 100644
index 18fa8c957..000000000
--- a/mod/twitter/manifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<plugin_manifest xmlns="http://www.elgg.org/plugin_manifest/1.8">
- <name>Twitter Widget</name>
- <author>Core developers</author>
- <version>1.7</version>
- <category>bundled</category>
- <category>widget</category>
- <description>Elgg simple twitter widget</description>
- <website>http://www.elgg.org/</website>
- <copyright>See COPYRIGHT.txt</copyright>
- <license>GNU General Public License version 2</license>
- <requires>
- <type>elgg_release</type>
- <version>1.8</version>
- </requires>
-</plugin_manifest>
diff --git a/mod/twitter/start.php b/mod/twitter/start.php
deleted file mode 100644
index b793eadf0..000000000
--- a/mod/twitter/start.php
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-/**
- * Elgg twitter widget
- * This plugin allows users to pull in their twitter feed to display on their profile
- *
- * @package ElggTwitter
- */
-
-elgg_register_event_handler('init', 'system', 'twitter_init');
-
-function twitter_init() {
- elgg_extend_view('css/elgg', 'twitter/css');
- elgg_register_widget_type('twitter', elgg_echo('twitter:title'), elgg_echo('twitter:info'));
-}
diff --git a/mod/twitter/views/default/twitter/css.php b/mod/twitter/views/default/twitter/css.php
deleted file mode 100644
index eb0cda98a..000000000
--- a/mod/twitter/views/default/twitter/css.php
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-/**
- * Elgg Twitter CSS
- *
- * @package ElggTwitter
- */
-?>
-
-#twitter_widget {
- margin:0 10px 0 10px;
-}
-#twitter_widget ul {
- margin:0;
- padding:0;
-}
-#twitter_widget li {
- list-style-image:none;
- list-style-position:outside;
- list-style-type:none;
- margin:0 0 5px 0;
- padding:0;
- overflow-x: hidden;
- border: 2px solid #dedede;
- -webkit-border-radius: 8px;
- -moz-border-radius: 8px;
- border-radius: 8px;
-}
-#twitter_widget li span {
- color:#666666;
- background:white;
-
- -webkit-border-radius: 8px;
- -moz-border-radius: 8px;
- border-radius: 8px;
-
- padding:5px;
- display:block;
-}
-p.visit_twitter a {
- background:url(<?php echo elgg_get_site_url(); ?>mod/twitter/graphics/twitter16px.png) left no-repeat;
- padding:0 0 0 20px;
- margin:0;
-}
-p.twitter_username .input-text {
- width:200px;
-}
-.visit_twitter {
- background:white;
-
- -webkit-border-radius: 8px;
- -moz-border-radius: 8px;
- border-radius: 8px;
-
- padding:2px;
- margin:0 0 5px 0;
-}
-#twitter_widget li > a {
- display:block;
- margin:0 0 0 4px;
-}
-#twitter_widget li span a {
- display:inline !important;
-} \ No newline at end of file
diff --git a/mod/twitter/views/default/widgets/twitter/content.php b/mod/twitter/views/default/widgets/twitter/content.php
deleted file mode 100644
index caefd369a..000000000
--- a/mod/twitter/views/default/widgets/twitter/content.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-/**
- * Elgg twitter view page
- *
- * @package ElggTwitter
- */
-
-$username = $vars['entity']->twitter_username;
-
-if (empty($username)) {
- echo "<p>" . elgg_echo("twitter:notset") . "</p>";
- return;
-}
-
-$username_is_valid = preg_match('~^[a-zA-Z0-9_]{1,20}$~', $username);
-if (!$username_is_valid) {
- echo "<p>" . elgg_echo("twitter:invalid") . "</p>";
- return;
-}
-
-
-$num = $vars['entity']->twitter_num;
-if (empty($num)) {
- $num = 5;
-}
-
-// @todo upgrade to 1.1 API https://dev.twitter.com/docs/api/1.1/get/statuses/home_timeline
-$script_url = "https://api.twitter.com/1/statuses/user_timeline/" . urlencode($username) . ".json"
- . "?callback=twitterCallback2&count=" . (int) $num;
-
-?>
-<div id="twitter_widget">
- <ul id="twitter_update_list"></ul>
- <p class="visit_twitter"><?php echo elgg_view('output/url', array(
- 'text' => elgg_echo("twitter:visit"),
- 'href' => 'http://twitter.com/' . urlencode($username),
- 'is_trusted' => true,
- )) ?></p>
- <script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"></script>
- <script type="text/javascript" src="<?php echo htmlspecialchars($script_url, ENT_QUOTES, 'UTF-8') ?>"></script>
-</div>
diff --git a/mod/twitter/views/default/widgets/twitter/edit.php b/mod/twitter/views/default/widgets/twitter/edit.php
deleted file mode 100644
index c3fc6f0d5..000000000
--- a/mod/twitter/views/default/widgets/twitter/edit.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-
-/**
- * Elgg twitter edit page
- *
- * @package ElggTwitter
- */
-
-?>
-<div>
- <?php echo elgg_echo("twitter:username"); ?>
- <?php echo elgg_view('input/text', array(
- 'name' => 'params[twitter_username]',
- 'value' => $vars['entity']->twitter_username,
- )) ?>
-</div>
-<div>
- <?php echo elgg_echo("twitter:num"); ?>
- <?php echo elgg_view('input/text', array(
- 'name' => 'params[twitter_num]',
- 'value' => $vars['entity']->twitter_num,
- )) ?>
- <span class="elgg-text-help"><?php echo elgg_echo("twitter:apibug"); ?></span>
-</div> \ No newline at end of file
diff --git a/mod/twitter_api/languages/en.php b/mod/twitter_api/languages/en.php
index f4b3c7f94..a6f4b40a5 100644
--- a/mod/twitter_api/languages/en.php
+++ b/mod/twitter_api/languages/en.php
@@ -25,7 +25,9 @@ $english = array(
'twitter_api:revoke:success' => 'Twitter access has been revoked.',
- 'twitter_api:login' => 'Allow existing users who have connected their Twitter account to sign in with Twitter?',
+ 'twitter_api:post_to_twitter' => "Send users' wire posts to Twitter?",
+
+ 'twitter_api:login' => 'Allow users to sign in with Twitter?',
'twitter_api:new_users' => 'Allow new users to sign up using their Twitter account even if user registration is disabled?',
'twitter_api:login:success' => 'You have been logged in.',
'twitter_api:login:error' => 'Unable to login with Twitter.',
diff --git a/mod/twitter_api/lib/twitter_api.php b/mod/twitter_api/lib/twitter_api.php
index e163d2b3e..a7b971876 100644
--- a/mod/twitter_api/lib/twitter_api.php
+++ b/mod/twitter_api/lib/twitter_api.php
@@ -6,6 +6,27 @@
*/
/**
+ * Get the API wrapper object
+ *
+ * @param string $oauth_token User's OAuth token
+ * @param string $oauth_token_secret User's OAuth secret
+ * @return TwitterOAuth|null
+ */
+function twitter_api_get_api_object($oauth_token = null, $oauth_token_secret = null) {
+ $consumer_key = elgg_get_plugin_setting('consumer_key', 'twitter_api');
+ $consumer_secret = elgg_get_plugin_setting('consumer_secret', 'twitter_api');
+ if (!($consumer_key && $consumer_secret)) {
+ return null;
+ }
+
+ $api = new TwitterOAuth($consumer_key, $consumer_secret, $oauth_token, $oauth_token_secret);
+ if ($api) {
+ $api->host = "https://api.twitter.com/1.1/";
+ }
+ return $api;
+}
+
+/**
* Tests if the system admin has enabled Sign-On-With-Twitter
*
* @param void
@@ -94,7 +115,7 @@ function twitter_api_login() {
$forward = $login_metadata['forward'];
}
- if (!isset($token['oauth_token']) or !isset($token['oauth_token_secret'])) {
+ if (!isset($token['oauth_token']) || !isset($token['oauth_token_secret'])) {
register_error(elgg_echo('twitter_api:login:error'));
forward();
}
@@ -121,9 +142,7 @@ function twitter_api_login() {
forward();
}
} else {
- $consumer_key = elgg_get_plugin_setting('consumer_key', 'twitter_api');
- $consumer_secret = elgg_get_plugin_setting('consumer_secret', 'twitter_api');
- $api = new TwitterOAuth($consumer_key, $consumer_secret, $token['oauth_token'], $token['oauth_token_secret']);
+ $api = twitter_api_get_api_object($token['oauth_token'], $token['oauth_token_secret']);
$twitter = $api->get('account/verify_credentials');
// backward compatibility for deprecated Twitter Login plugin
@@ -255,7 +274,7 @@ function twitter_api_update_user_avatar($user, $file_location) {
* to establish session request tokens.
*/
function twitter_api_authorize() {
- $token = twitter_api_get_access_token();
+ $token = twitter_api_get_access_token(get_input('oauth_verifier'));
if (!isset($token['oauth_token']) || !isset($token['oauth_token_secret'])) {
register_error(elgg_echo('twitter_api:authorize:error'));
forward('settings/plugins', 'twitter_api');
@@ -314,11 +333,8 @@ function twitter_api_revoke() {
function twitter_api_get_authorize_url($callback = NULL, $login = true) {
global $SESSION;
- $consumer_key = elgg_get_plugin_setting('consumer_key', 'twitter_api');
- $consumer_secret = elgg_get_plugin_setting('consumer_secret', 'twitter_api');
-
// request tokens from Twitter
- $twitter = new TwitterOAuth($consumer_key, $consumer_secret);
+ $twitter = twitter_api_get_api_object();
$token = $twitter->getRequestToken($callback);
// save token in session for use after authorization
@@ -340,16 +356,13 @@ function twitter_api_get_access_token($oauth_verifier = FALSE) {
/* @var ElggSession $SESSION */
global $SESSION;
- $consumer_key = elgg_get_plugin_setting('consumer_key', 'twitter_api');
- $consumer_secret = elgg_get_plugin_setting('consumer_secret', 'twitter_api');
-
// retrieve stored tokens
$oauth_token = $SESSION['twitter_api']['oauth_token'];
$oauth_token_secret = $SESSION['twitter_api']['oauth_token_secret'];
unset($SESSION['twitter_api']);
// fetch an access token
- $api = new TwitterOAuth($consumer_key, $consumer_secret, $oauth_token, $oauth_token_secret);
+ $api = twitter_api_get_api_object($oauth_token, $oauth_token_secret);
return $api->getAccessToken($oauth_verifier);
}
@@ -367,4 +380,4 @@ function twitter_api_allow_new_users_with_twitter() {
}
return false;
-} \ No newline at end of file
+}
diff --git a/mod/twitter_api/manifest.xml b/mod/twitter_api/manifest.xml
index 86bba4b50..3af866bba 100644
--- a/mod/twitter_api/manifest.xml
+++ b/mod/twitter_api/manifest.xml
@@ -2,7 +2,7 @@
<plugin_manifest xmlns="http://www.elgg.org/plugin_manifest/1.8">
<name>Twitter API</name>
<author>Core developers</author>
- <version>1.8</version>
+ <version>1.8.15</version>
<description>Allows users to authenticate their Elgg account with Twitter.</description>
<category>api</category>
<category>bundled</category>
@@ -14,16 +14,16 @@
<version>1.8</version>
</requires>
<requires>
- <type>plugin</type>
- <name>oauth_api</name>
- </requires>
- <requires>
<type>php_extension</type>
<name>curl</name>
</requires>
<conflicts>
<type>plugin</type>
+ <name>oauth_api</name>
+ </conflicts>
+ <conflicts>
+ <type>plugin</type>
<name>twitterservice</name>
</conflicts>
</plugin_manifest>
diff --git a/mod/twitter_api/pages/twitter_api/interstitial.php b/mod/twitter_api/pages/twitter_api/interstitial.php
index d1f1ac20c..23b5069cb 100644
--- a/mod/twitter_api/pages/twitter_api/interstitial.php
+++ b/mod/twitter_api/pages/twitter_api/interstitial.php
@@ -8,9 +8,7 @@
$title = elgg_echo('twitter_api:interstitial:settings');
-$site = get_config('site');
-$content = elgg_echo('twitter_api:interstitial:description', array($site->name));
-$content .= elgg_view_form('twitter_api/interstitial_settings');
+$content = elgg_view_form('twitter_api/interstitial_settings');
$params = array(
'content' => $content,
diff --git a/mod/twitter_api/start.php b/mod/twitter_api/start.php
index e6221de6b..7318ac55d 100644
--- a/mod/twitter_api/start.php
+++ b/mod/twitter_api/start.php
@@ -35,8 +35,10 @@ function twitter_api_init() {
// register Walled Garden public pages
elgg_register_plugin_hook_handler('public_pages', 'walled_garden', 'twitter_api_public_pages');
- // push status messages to twitter
- elgg_register_plugin_hook_handler('status', 'user', 'twitter_api_tweet');
+ // push wire post messages to twitter
+ if (elgg_get_plugin_setting('wire_posts', 'twitter_api') == 'yes') {
+ elgg_register_plugin_hook_handler('status', 'user', 'twitter_api_tweet');
+ }
$actions = dirname(__FILE__) . '/actions/twitter_api';
elgg_register_action('twitter_api/interstitial_settings', "$actions/interstitial_settings.php", 'logged_in');
@@ -115,13 +117,6 @@ function twitter_api_tweet($hook, $type, $returnvalue, $params) {
// @todo - allow admin to select origins?
- // check admin settings
- $consumer_key = elgg_get_plugin_setting('consumer_key', 'twitter_api');
- $consumer_secret = elgg_get_plugin_setting('consumer_secret', 'twitter_api');
- if (!($consumer_key && $consumer_secret)) {
- return;
- }
-
// check user settings
$user_id = $params['user']->getGUID();
$access_key = elgg_get_plugin_user_setting('access_key', $user_id, 'twitter_api');
@@ -130,8 +125,11 @@ function twitter_api_tweet($hook, $type, $returnvalue, $params) {
return;
}
- // send tweet
- $api = new TwitterOAuth($consumer_key, $consumer_secret, $access_key, $access_secret);
+ $api = twitter_api_get_api_object($access_key, $access_secret);
+ if (!$api) {
+ return;
+ }
+
$api->post('statuses/update', array('status' => $params['message']));
}
@@ -143,12 +141,6 @@ function twitter_api_tweet($hook, $type, $returnvalue, $params) {
* @return array
*/
function twitter_api_fetch_tweets($user_guid, $options = array()) {
- // check admin settings
- $consumer_key = elgg_get_plugin_setting('consumer_key', 'twitter_api');
- $consumer_secret = elgg_get_plugin_setting('consumer_secret', 'twitter_api');
- if (!($consumer_key && $consumer_secret)) {
- return FALSE;
- }
// check user settings
$access_key = elgg_get_plugin_user_setting('access_key', $user_guid, 'twitter_api');
@@ -157,8 +149,11 @@ function twitter_api_fetch_tweets($user_guid, $options = array()) {
return FALSE;
}
- // fetch tweets
- $api = new TwitterOAuth($consumer_key, $consumer_secret, $access_key, $access_secret);
+ $api = twitter_api_get_api_object($access_key, $access_secret);
+ if (!$api) {
+ return FALSE;
+ }
+
return $api->get('statuses/user_timeline', $options);
}
diff --git a/mod/twitter_api/vendors/twitteroauth/OAuth.php b/mod/twitter_api/vendors/twitteroauth/OAuth.php
index e132a5bc8..e76304146 100644
--- a/mod/twitter_api/vendors/twitteroauth/OAuth.php
+++ b/mod/twitter_api/vendors/twitteroauth/OAuth.php
@@ -1,6 +1,12 @@
<?php
// vim: foldmethod=marker
+/* Generic exception class
+ */
+class OAuthException extends Exception {
+ // pass
+}
+
class OAuthConsumer {
public $key;
public $secret;
@@ -46,12 +52,56 @@ class OAuthToken {
}
}
-class twitterOAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod_HMAC_SHA1 {/*{{{*/
- function get_name() {/*{{{*/
+/**
+ * A class for implementing a Signature Method
+ * See section 9 ("Signing Requests") in the spec
+ */
+abstract class OAuthSignatureMethod {
+ /**
+ * Needs to return the name of the Signature Method (ie HMAC-SHA1)
+ * @return string
+ */
+ abstract public function get_name();
+
+ /**
+ * Build up the signature
+ * NOTE: The output of this function MUST NOT be urlencoded.
+ * the encoding is handled in OAuthRequest when the final
+ * request is serialized
+ * @param OAuthRequest $request
+ * @param OAuthConsumer $consumer
+ * @param OAuthToken $token
+ * @return string
+ */
+ abstract public function build_signature($request, $consumer, $token);
+
+ /**
+ * Verifies that a given signature is correct
+ * @param OAuthRequest $request
+ * @param OAuthConsumer $consumer
+ * @param OAuthToken $token
+ * @param string $signature
+ * @return bool
+ */
+ public function check_signature($request, $consumer, $token, $signature) {
+ $built = $this->build_signature($request, $consumer, $token);
+ return $built == $signature;
+ }
+}
+
+/**
+ * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
+ * where the Signature Base String is the text and the key is the concatenated values (each first
+ * encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
+ * character (ASCII code 38) even if empty.
+ * - Chapter 9.2 ("HMAC-SHA1")
+ */
+class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {
+ function get_name() {
return "HMAC-SHA1";
- }/*}}}*/
+ }
- public function build_signature($request, $consumer, $token) {/*{{{*/
+ public function build_signature($request, $consumer, $token) {
$base_string = $request->get_signature_base_string();
$request->base_string = $base_string;
@@ -63,16 +113,111 @@ class twitterOAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod_HMAC_SH
$key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
$key = implode('&', $key_parts);
- return base64_encode( hash_hmac('sha1', $base_string, $key, true));
- }/*}}}*/
+ return base64_encode(hash_hmac('sha1', $base_string, $key, true));
+ }
+}
- public function check_signature(&$request, $consumer, $token, $signature) {
- $built = $this->build_signature($request, $consumer, $token);
- return $built == $signature;
+/**
+ * The PLAINTEXT method does not provide any security protection and SHOULD only be used
+ * over a secure channel such as HTTPS. It does not use the Signature Base String.
+ * - Chapter 9.4 ("PLAINTEXT")
+ */
+class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {
+ public function get_name() {
+ return "PLAINTEXT";
+ }
+
+ /**
+ * oauth_signature is set to the concatenated encoded values of the Consumer Secret and
+ * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
+ * empty. The result MUST be encoded again.
+ * - Chapter 9.4.1 ("Generating Signatures")
+ *
+ * Please note that the second encoding MUST NOT happen in the SignatureMethod, as
+ * OAuthRequest handles this!
+ */
+ public function build_signature($request, $consumer, $token) {
+ $key_parts = array(
+ $consumer->secret,
+ ($token) ? $token->secret : ""
+ );
+
+ $key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
+ $key = implode('&', $key_parts);
+ $request->base_string = $key;
+
+ return $key;
}
-}/*}}}*/
+}
+
+/**
+ * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in
+ * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for
+ * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a
+ * verified way to the Service Provider, in a manner which is beyond the scope of this
+ * specification.
+ * - Chapter 9.3 ("RSA-SHA1")
+ */
+abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
+ public function get_name() {
+ return "RSA-SHA1";
+ }
+
+ // Up to the SP to implement this lookup of keys. Possible ideas are:
+ // (1) do a lookup in a table of trusted certs keyed off of consumer
+ // (2) fetch via http using a url provided by the requester
+ // (3) some sort of specific discovery code based on request
+ //
+ // Either way should return a string representation of the certificate
+ protected abstract function fetch_public_cert(&$request);
+
+ // Up to the SP to implement this lookup of keys. Possible ideas are:
+ // (1) do a lookup in a table of trusted certs keyed off of consumer
+ //
+ // Either way should return a string representation of the certificate
+ protected abstract function fetch_private_cert(&$request);
+
+ public function build_signature($request, $consumer, $token) {
+ $base_string = $request->get_signature_base_string();
+ $request->base_string = $base_string;
+
+ // Fetch the private key cert based on the request
+ $cert = $this->fetch_private_cert($request);
+
+ // Pull the private key ID from the certificate
+ $privatekeyid = openssl_get_privatekey($cert);
+
+ // Sign using the key
+ $ok = openssl_sign($base_string, $signature, $privatekeyid);
+
+ // Release the key resource
+ openssl_free_key($privatekeyid);
+
+ return base64_encode($signature);
+ }
+
+ public function check_signature($request, $consumer, $token, $signature) {
+ $decoded_sig = base64_decode($signature);
+
+ $base_string = $request->get_signature_base_string();
+
+ // Fetch the public key cert based on the request
+ $cert = $this->fetch_public_cert($request);
+
+ // Pull the public key ID from the certificate
+ $publickeyid = openssl_get_publickey($cert);
-class twitterOAuthRequest extends OAuthRequest {
+ // Check the computed signature against the one passed in the query
+ $ok = openssl_verify($base_string, $decoded_sig, $publickeyid);
+
+ // Release the key resource
+ openssl_free_key($publickeyid);
+
+ return $ok == 1;
+ }
+}
+
+class OAuthRequest {
private $parameters;
private $http_method;
private $http_url;
@@ -138,7 +283,7 @@ class twitterOAuthRequest extends OAuthRequest {
}
- return new twitterOAuthRequest($http_method, $http_url, $parameters);
+ return new OAuthRequest($http_method, $http_url, $parameters);
}
/**
@@ -146,16 +291,16 @@ class twitterOAuthRequest extends OAuthRequest {
*/
public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {
@$parameters or $parameters = array();
- $defaults = array("oauth_version" => twitterOAuthRequest::$version,
- "oauth_nonce" => twitterOAuthRequest::generate_nonce(),
- "oauth_timestamp" => twitterOAuthRequest::generate_timestamp(),
+ $defaults = array("oauth_version" => OAuthRequest::$version,
+ "oauth_nonce" => OAuthRequest::generate_nonce(),
+ "oauth_timestamp" => OAuthRequest::generate_timestamp(),
"oauth_consumer_key" => $consumer->key);
if ($token)
$defaults['oauth_token'] = $token->key;
$parameters = array_merge($defaults, $parameters);
- return new twitterOAuthRequest($http_method, $http_url, $parameters);
+ return new OAuthRequest($http_method, $http_url, $parameters);
}
public function set_parameter($name, $value, $allow_duplicates = true) {
@@ -333,6 +478,217 @@ class twitterOAuthRequest extends OAuthRequest {
}
}
+class OAuthServer {
+ protected $timestamp_threshold = 300; // in seconds, five minutes
+ protected $version = '1.0'; // hi blaine
+ protected $signature_methods = array();
+
+ protected $data_store;
+
+ function __construct($data_store) {
+ $this->data_store = $data_store;
+ }
+
+ public function add_signature_method($signature_method) {
+ $this->signature_methods[$signature_method->get_name()] =
+ $signature_method;
+ }
+
+ // high level functions
+
+ /**
+ * process a request_token request
+ * returns the request token on success
+ */
+ public function fetch_request_token(&$request) {
+ $this->get_version($request);
+
+ $consumer = $this->get_consumer($request);
+
+ // no token required for the initial token request
+ $token = NULL;
+
+ $this->check_signature($request, $consumer, $token);
+
+ // Rev A change
+ $callback = $request->get_parameter('oauth_callback');
+ $new_token = $this->data_store->new_request_token($consumer, $callback);
+
+ return $new_token;
+ }
+
+ /**
+ * process an access_token request
+ * returns the access token on success
+ */
+ public function fetch_access_token(&$request) {
+ $this->get_version($request);
+
+ $consumer = $this->get_consumer($request);
+
+ // requires authorized request token
+ $token = $this->get_token($request, $consumer, "request");
+
+ $this->check_signature($request, $consumer, $token);
+
+ // Rev A change
+ $verifier = $request->get_parameter('oauth_verifier');
+ $new_token = $this->data_store->new_access_token($token, $consumer, $verifier);
+
+ return $new_token;
+ }
+
+ /**
+ * verify an api call, checks all the parameters
+ */
+ public function verify_request(&$request) {
+ $this->get_version($request);
+ $consumer = $this->get_consumer($request);
+ $token = $this->get_token($request, $consumer, "access");
+ $this->check_signature($request, $consumer, $token);
+ return array($consumer, $token);
+ }
+
+ // Internals from here
+ /**
+ * version 1
+ */
+ private function get_version(&$request) {
+ $version = $request->get_parameter("oauth_version");
+ if (!$version) {
+ // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
+ // Chapter 7.0 ("Accessing Protected Ressources")
+ $version = '1.0';
+ }
+ if ($version !== $this->version) {
+ throw new OAuthException("OAuth version '$version' not supported");
+ }
+ return $version;
+ }
+
+ /**
+ * figure out the signature with some defaults
+ */
+ private function get_signature_method(&$request) {
+ $signature_method =
+ @$request->get_parameter("oauth_signature_method");
+
+ if (!$signature_method) {
+ // According to chapter 7 ("Accessing Protected Ressources") the signature-method
+ // parameter is required, and we can't just fallback to PLAINTEXT
+ throw new OAuthException('No signature method parameter. This parameter is required');
+ }
+
+ if (!in_array($signature_method,
+ array_keys($this->signature_methods))) {
+ throw new OAuthException(
+ "Signature method '$signature_method' not supported " .
+ "try one of the following: " .
+ implode(", ", array_keys($this->signature_methods))
+ );
+ }
+ return $this->signature_methods[$signature_method];
+ }
+
+ /**
+ * try to find the consumer for the provided request's consumer key
+ */
+ private function get_consumer(&$request) {
+ $consumer_key = @$request->get_parameter("oauth_consumer_key");
+ if (!$consumer_key) {
+ throw new OAuthException("Invalid consumer key");
+ }
+
+ $consumer = $this->data_store->lookup_consumer($consumer_key);
+ if (!$consumer) {
+ throw new OAuthException("Invalid consumer");
+ }
+
+ return $consumer;
+ }
+
+ /**
+ * try to find the token for the provided request's token key
+ */
+ private function get_token(&$request, $consumer, $token_type="access") {
+ $token_field = @$request->get_parameter('oauth_token');
+ $token = $this->data_store->lookup_token(
+ $consumer, $token_type, $token_field
+ );
+ if (!$token) {
+ throw new OAuthException("Invalid $token_type token: $token_field");
+ }
+ return $token;
+ }
+
+ /**
+ * all-in-one function to check the signature on a request
+ * should guess the signature method appropriately
+ */
+ private function check_signature(&$request, $consumer, $token) {
+ // this should probably be in a different method
+ $timestamp = @$request->get_parameter('oauth_timestamp');
+ $nonce = @$request->get_parameter('oauth_nonce');
+
+ $this->check_timestamp($timestamp);
+ $this->check_nonce($consumer, $token, $nonce, $timestamp);
+
+ $signature_method = $this->get_signature_method($request);
+
+ $signature = $request->get_parameter('oauth_signature');
+ $valid_sig = $signature_method->check_signature(
+ $request,
+ $consumer,
+ $token,
+ $signature
+ );
+
+ if (!$valid_sig) {
+ throw new OAuthException("Invalid signature");
+ }
+ }
+
+ /**
+ * check that the timestamp is new enough
+ */
+ private function check_timestamp($timestamp) {
+ if( ! $timestamp )
+ throw new OAuthException(
+ 'Missing timestamp parameter. The parameter is required'
+ );
+
+ // verify that timestamp is recentish
+ $now = time();
+ if (abs($now - $timestamp) > $this->timestamp_threshold) {
+ throw new OAuthException(
+ "Expired timestamp, yours $timestamp, ours $now"
+ );
+ }
+ }
+
+ /**
+ * check that the nonce is not repeated
+ */
+ private function check_nonce($consumer, $token, $nonce, $timestamp) {
+ if( ! $nonce )
+ throw new OAuthException(
+ 'Missing nonce parameter. The parameter is required'
+ );
+
+ // verify that the nonce is uniqueish
+ $found = $this->data_store->lookup_nonce(
+ $consumer,
+ $token,
+ $nonce,
+ $timestamp
+ );
+ if ($found) {
+ throw new OAuthException("Nonce already used: $nonce");
+ }
+ }
+
+}
+
class OAuthDataStore {
function lookup_consumer($consumer_key) {
// implement me
@@ -514,5 +870,3 @@ class OAuthUtil {
return implode('&', $pairs);
}
}
-
-?>
diff --git a/mod/twitter_api/vendors/twitteroauth/README b/mod/twitter_api/vendors/twitteroauth/README
index 33cb91f21..c9a17ce4b 100644
--- a/mod/twitter_api/vendors/twitteroauth/README
+++ b/mod/twitter_api/vendors/twitteroauth/README
@@ -1,7 +1,114 @@
-Abraham Williams | abraham@poseurte.ch | http://abrah.am | @abraham
+TwitterOAuth
+------------
-The first PHP library for working with Twitter's OAuth API.
+PHP library for working with Twitter's OAuth API.
-Documentation: http://wiki.github.com/abraham/twitteroauth/documentation
-Source: http://github.com/abraham/twitteroauth
-Twitter: http://apiwiki.twitter.com
+Flow Overview
+=============
+
+1. Build TwitterOAuth object using client credentials.
+2. Request temporary credentials from Twitter.
+3. Build authorize URL for Twitter.
+4. Redirect user to authorize URL.
+5. User authorizes access and returns from Twitter.
+6. Rebuild TwitterOAuth object with client credentials and temporary credentials.
+7. Get token credentials from Twitter.
+8. Rebuild TwitterOAuth object with client credentials and token credentials.
+9. Query Twitter API.
+
+Terminology
+===========
+
+The terminology has changed since 0.1.x to better match the draft-hammer-oauth IETF
+RFC. You can read that at http://tools.ietf.org/html/draft-hammer-oauth. Some of the
+terms will differ from those Twitter uses as well.
+
+client credentials - Consumer key/secret you get when registering an app with Twitter.
+temporary credentials - Previously known as the request token.
+token credentials - Previously known as the access token.
+
+Parameters
+==========
+
+There are a number of parameters you can modify after creating a TwitterOAuth object.
+
+Switch an existing TwitterOAuth install to use version 1.1 of the API.
+
+ $connection->$host = "https://api.twitter.com/1.1/";
+
+Custom useragent.
+
+ $connection->useragent = 'Custom useragent string';
+
+Verify Twitters SSL certificate.
+
+ $connection->ssl_verifypeer = TRUE;
+
+There are several more you can find in TwitterOAuth.php.
+
+Extended flow using example code
+================================
+
+To use TwitterOAuth with the Twitter API you need *TwitterOAuth.php*, *OAuth.php* and
+client credentials. You can get client credentials by registering your application at
+[dev.twitter.com/apps](https://dev.twitter.com/apps).
+
+Users start out on connect.php which displays the "Sign in with Twitter" image hyperlinked
+to redirect.php. This button should be displayed on your homepage in your login section. The
+client credentials are saved in config.php as `CONSUMER_KEY` and `CONSUMER_SECRET`. You can
+save a static callback URL in the app settings page, in the config file or use a dynamic
+callback URL later in step 2. In example use https://example.com/callback.php.
+
+1) When a user lands on redirect.php we build a new TwitterOAuth object using the client credentials.
+If you have your own configuration method feel free to use it instead of config.php.
+
+ $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET); // Use config.php client credentials
+ $connection = new TwitterOAuth('abc890', '123xyz');
+
+2) Using the built $connection object you will ask Twitter for temporary credentials. The `oauth_callback` value is required.
+
+ $temporary_credentials = $connection->getRequestToken(OAUTH_CALLBACK); // Use config.php callback URL.
+
+3) Now that we have temporary credentials the user has to go to Twitter and authorize the app
+to access and updates their data. You can also pass a second parameter of FALSE to not use [Sign
+in with Twitter](https://dev.twitter.com/docs/auth/sign-twitter).
+
+ $redirect_url = $connection->getAuthorizeURL($temporary_credentials); // Use Sign in with Twitter
+ $redirect_url = $connection->getAuthorizeURL($temporary_credentials, FALSE);
+
+4) You will now have a Twitter URL that you must send the user to.
+
+ https://api.twitter.com/oauth/authenticate?oauth_token=xyz123
+
+5) The user is now on twitter.com and may have to login. Once authenticated with Twitter they will
+will either have to click on allow/deny, or will be automatically redirected back to the callback.
+
+6) Now that the user has returned to callback.php and allowed access we need to build a new
+TwitterOAuth object using the temporary credentials.
+
+ $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $_SESSION['oauth_token'],
+ $_SESSION['oauth_token_secret']);
+
+7) Now we ask Twitter for long lasting token credentials. These are specific to the application
+and user and will act like password to make future requests. Normally the token credentials would
+get saved in your database but for this example we are just using sessions.
+
+ $token_credentials = $connection->getAccessToken($_REQUEST['oauth_verifier']);
+
+8) With the token credentials we build a new TwitterOAuth object.
+
+ $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $token_credentials['oauth_token'],
+ $token_credentials['oauth_token_secret']);
+
+9) And finally we can make requests authenticated as the user. You can GET, POST, and DELETE API
+methods. Directly copy the path from the API documentation and add an array of any parameter
+you wish to include for the API method such as curser or in_reply_to_status_id.
+
+ $account = $connection->get('account/verify_credentials');
+ $status = $connection->post('statuses/update', array('status' => 'Text of status here', 'in_reply_to_status_id' => 123456));
+ $status = $connection->delete('statuses/destroy/12345');
+
+Contributors
+============
+
+* [Abraham Williams](https://twitter.com/abraham) - Main developer, current maintainer.
diff --git a/mod/twitter_api/vendors/twitteroauth/twitterOAuth.php b/mod/twitter_api/vendors/twitteroauth/twitterOAuth.php
index f36e6158d..4c2447c46 100644
--- a/mod/twitter_api/vendors/twitteroauth/twitterOAuth.php
+++ b/mod/twitter_api/vendors/twitteroauth/twitterOAuth.php
@@ -57,7 +57,7 @@ class TwitterOAuth {
* construct TwitterOAuth object
*/
function __construct($consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) {
- $this->sha1_method = new twitterOAuthSignatureMethod_HMAC_SHA1();
+ $this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1();
$this->consumer = new OAuthConsumer($consumer_key, $consumer_secret);
if (!empty($oauth_token) && !empty($oauth_token_secret)) {
$this->token = new OAuthConsumer($oauth_token, $oauth_token_secret);
@@ -72,11 +72,9 @@ class TwitterOAuth {
*
* @returns a key/value array containing oauth_token and oauth_token_secret
*/
- function getRequestToken($oauth_callback = NULL) {
+ function getRequestToken($oauth_callback) {
$parameters = array();
- if (!empty($oauth_callback)) {
- $parameters['oauth_callback'] = $oauth_callback;
- }
+ $parameters['oauth_callback'] = $oauth_callback;
$request = $this->oAuthRequest($this->requestTokenURL(), 'GET', $parameters);
$token = OAuthUtil::parse_parameters($request);
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
@@ -108,11 +106,9 @@ class TwitterOAuth {
* "user_id" => "9436992",
* "screen_name" => "abraham")
*/
- function getAccessToken($oauth_verifier = FALSE) {
+ function getAccessToken($oauth_verifier) {
$parameters = array();
- if (!empty($oauth_verifier)) {
- $parameters['oauth_verifier'] = $oauth_verifier;
- }
+ $parameters['oauth_verifier'] = $oauth_verifier;
$request = $this->oAuthRequest($this->accessTokenURL(), 'GET', $parameters);
$token = OAuthUtil::parse_parameters($request);
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
@@ -179,7 +175,7 @@ class TwitterOAuth {
if (strrpos($url, 'https://') !== 0 && strrpos($url, 'http://') !== 0) {
$url = "{$this->host}{$url}.{$this->format}";
}
- $request = twitterOAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $parameters);
+ $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $parameters);
$request->sign_request($this->sha1_method, $this->consumer, $this->token);
switch ($method) {
case 'GET':
diff --git a/mod/twitter_api/views/default/forms/twitter_api/interstitial_settings.php b/mod/twitter_api/views/default/forms/twitter_api/interstitial_settings.php
index cad2be345..b4882bb7f 100644
--- a/mod/twitter_api/views/default/forms/twitter_api/interstitial_settings.php
+++ b/mod/twitter_api/views/default/forms/twitter_api/interstitial_settings.php
@@ -3,6 +3,11 @@
* Make the user set up some alternative ways to login.
*/
+echo '<div>';
+$site = get_config('site');
+echo elgg_echo('twitter_api:interstitial:description', array($site->name));
+echo '</div>';
+
$user = elgg_get_logged_in_user_entity();
if (elgg_is_sticky_form('twitter_api_interstitial')) {
@@ -51,7 +56,7 @@ echo elgg_view_module('info', $title, $body);
// buttons
echo elgg_view('input/submit', array(
- 'text' => elgg_echo('save')
+ 'value' => elgg_echo('save')
));
echo elgg_view('output/url', array(
diff --git a/mod/twitter_api/views/default/plugins/twitter_api/settings.php b/mod/twitter_api/views/default/plugins/twitter_api/settings.php
index 0b9afd4cf..3a3ec93a2 100644
--- a/mod/twitter_api/views/default/plugins/twitter_api/settings.php
+++ b/mod/twitter_api/views/default/plugins/twitter_api/settings.php
@@ -39,12 +39,27 @@ $new_users_with_twitter_view = elgg_view('input/dropdown', array(
'value' => $vars['entity']->new_users ? $vars['entity']->new_users : 'no',
));
+$post_to_twitter = '';
+if (elgg_is_active_plugin('thewire')) {
+ $post_to_twitter_string = elgg_echo('twitter_api:post_to_twitter');
+ $post_to_twitter_view = elgg_view('input/dropdown', array(
+ 'name' => 'params[wire_posts]',
+ 'options_values' => array(
+ 'yes' => elgg_echo('option:yes'),
+ 'no' => elgg_echo('option:no'),
+ ),
+ 'value' => $vars['entity']->wire_posts ? $vars['entity']->wire_posts : 'no',
+ ));
+ $post_to_twitter = "<div>$post_to_twitter_string $post_to_twitter_view</div>";
+}
+
$settings = <<<__HTML
<div class="elgg-content-thin mtm"><p>$instructions</p></div>
<div><label>$consumer_key_string</label><br /> $consumer_key_view</div>
<div><label>$consumer_secret_string</label><br /> $consumer_secret_view</div>
<div>$sign_on_with_twitter_string $sign_on_with_twitter_view</div>
<div>$new_users_with_twitter $new_users_with_twitter_view</div>
+$post_to_twitter
__HTML;
echo $settings;
diff --git a/pages/account/forgotten_password.php b/pages/account/forgotten_password.php
index bf6ef87e0..f464f98c9 100644
--- a/pages/account/forgotten_password.php
+++ b/pages/account/forgotten_password.php
@@ -17,6 +17,11 @@ $content .= elgg_view_form('user/requestnewpassword', array(
'class' => 'elgg-form-account',
));
-$body = elgg_view_layout("one_column", array('content' => $content));
-
-echo elgg_view_page($title, $body);
+if (elgg_get_config('walled_garden')) {
+ elgg_load_css('elgg.walled_garden');
+ $body = elgg_view_layout('walled_garden', array('content' => $content));
+ echo elgg_view_page($title, $body, 'walled_garden');
+} else {
+ $body = elgg_view_layout('one_column', array('content' => $content));
+ echo elgg_view_page($title, $body);
+}
diff --git a/pages/account/login.php b/pages/account/login.php
index 14f65cc3f..6aa3752d0 100644
--- a/pages/account/login.php
+++ b/pages/account/login.php
@@ -15,6 +15,14 @@ if (elgg_is_logged_in()) {
forward('');
}
-$login_box = elgg_view('core/account/login_box');
-$content = elgg_view_layout('one_column', array('content' => $login_box));
-echo elgg_view_page(elgg_echo('login'), $content);
+$title = elgg_echo('login');
+$content = elgg_view('core/account/login_box');
+
+if (elgg_get_config('walled_garden')) {
+ elgg_load_css('elgg.walled_garden');
+ $body = elgg_view_layout('walled_garden', array('content' => $content));
+ echo elgg_view_page($title, $body, 'walled_garden');
+} else {
+ $body = elgg_view_layout('one_column', array('content' => $content));
+ echo elgg_view_page($title, $body);
+}
diff --git a/pages/account/register.php b/pages/account/register.php
index cf18a635b..2fe8b74c0 100644
--- a/pages/account/register.php
+++ b/pages/account/register.php
@@ -48,6 +48,11 @@ $content .= elgg_view_form('register', $form_params, $body_params);
$content .= elgg_view('help/register');
-$body = elgg_view_layout("one_column", array('content' => $content));
-
-echo elgg_view_page($title, $body);
+if (elgg_get_config('walled_garden')) {
+ elgg_load_css('elgg.walled_garden');
+ $body = elgg_view_layout('walled_garden', array('content' => $content));
+ echo elgg_view_page($title, $body, 'walled_garden');
+} else {
+ $body = elgg_view_layout('one_column', array('content' => $content));
+ echo elgg_view_page($title, $body);
+}
diff --git a/pages/account/reset_password.php b/pages/account/reset_password.php
index 6515bfc5d..3ab8ccf3e 100644
--- a/pages/account/reset_password.php
+++ b/pages/account/reset_password.php
@@ -30,6 +30,11 @@ $form = elgg_view_form('user/passwordreset', array('class' => 'elgg-form-account
$title = elgg_echo('resetpassword');
$content = elgg_view_title(elgg_echo('resetpassword')) . $form;
-$body = elgg_view_layout('one_column', array('content' => $content));
-
-echo elgg_view_page($title, $body);
+if (elgg_get_config('walled_garden')) {
+ elgg_load_css('elgg.walled_garden');
+ $body = elgg_view_layout('walled_garden', array('content' => $content));
+ echo elgg_view_page($title, $body, 'walled_garden');
+} else {
+ $body = elgg_view_layout('one_column', array('content' => $content));
+ echo elgg_view_page($title, $body);
+}
diff --git a/pages/avatar/edit.php b/pages/avatar/edit.php
index c71633b8b..56aede887 100644
--- a/pages/avatar/edit.php
+++ b/pages/avatar/edit.php
@@ -11,6 +11,11 @@ elgg_set_context('profile_edit');
$title = elgg_echo('avatar:edit');
$entity = elgg_get_page_owner_entity();
+if (!elgg_instanceof($entity, 'user') || !$entity->canEdit()) {
+ register_error(elgg_echo('avatar:noaccess'));
+ forward(REFERER);
+}
+
$content = elgg_view('core/avatar/upload', array('entity' => $entity));
// only offer the crop view if an avatar has been uploaded
diff --git a/pages/river.php b/pages/river.php
index 0e1511334..801d9f664 100644
--- a/pages/river.php
+++ b/pages/river.php
@@ -49,6 +49,7 @@ $content = elgg_view('core/river/filter', array('selector' => $selector));
$sidebar = elgg_view('core/river/sidebar');
$params = array(
+ 'title' => $title,
'content' => $content . $activity,
'sidebar' => $sidebar,
'filter_context' => $page_filter,
diff --git a/upgrade.php b/upgrade.php
index c5f158c61..d07b2a1da 100644
--- a/upgrade.php
+++ b/upgrade.php
@@ -46,7 +46,7 @@ if (get_input('upgrade') == 'upgrade') {
} else {
// if upgrading from < 1.8.0, check for the core view 'welcome' and bail if it's found.
- // see http://trac.elgg.org/ticket/3064
+ // see https://github.com/elgg/elgg/issues/3064
// we're not checking the view itself because it's likely themes will override this view.
// we're only concerned with core files.
$welcome = dirname(__FILE__) . '/views/default/welcome.php';
diff --git a/version.php b/version.php
index b5822b371..a94bf9d31 100644
--- a/version.php
+++ b/version.php
@@ -11,7 +11,7 @@
// YYYYMMDD = Elgg Date
// XX = Interim incrementer
-$version = 2013030600;
+$version = 2013052900;
// Human-friendly version name
-$release = '1.8.14';
+$release = '1.8.16';
diff --git a/views/default/css/admin.php b/views/default/css/admin.php
index ceeac71a2..3896ded5d 100644
--- a/views/default/css/admin.php
+++ b/views/default/css/admin.php
@@ -446,7 +446,8 @@ input {
.elgg-input-text,
.elgg-input-tags,
.elgg-input-url,
-.elgg-input-plaintext {
+.elgg-input-plaintext,
+.elgg-input-longtext {
width: 98%;
}
textarea {
@@ -1003,7 +1004,7 @@ a.elgg-button {
ENTITY MENU
*************************************** */
<?php // height depends on line height/font size ?>
-.elgg-menu-entity, elgg-menu-annotation {
+.elgg-menu-entity, .elgg-menu-annotation {
float: right;
margin-left: 15px;
font-size: 90%;
diff --git a/views/default/css/elements/navigation.php b/views/default/css/elements/navigation.php
index 62f370069..6b29e4c19 100644
--- a/views/default/css/elements/navigation.php
+++ b/views/default/css/elements/navigation.php
@@ -16,7 +16,7 @@
text-align: center;
}
.elgg-pagination li {
- display: inline;
+ display: inline-block;
margin: 0 6px 0 0;
text-align: center;
}
@@ -24,7 +24,8 @@
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
-
+
+ display: block;
padding: 2px 6px;
color: #4690d6;
border: 1px solid #4690d6;
@@ -449,7 +450,7 @@
ENTITY AND ANNOTATION
*************************************** */
<?php // height depends on line height/font size ?>
-.elgg-menu-entity, elgg-menu-annotation {
+.elgg-menu-entity, .elgg-menu-annotation {
float: right;
margin-left: 15px;
font-size: 90%;
diff --git a/views/default/css/ie.php b/views/default/css/ie.php
index 4bddd4d55..34ececa89 100644
--- a/views/default/css/ie.php
+++ b/views/default/css/ie.php
@@ -6,3 +6,11 @@
.elgg-avatar {
display: block;
}
+
+/* ie8 adds space to the top of .elgg-gallery which causes jumpiness if this is display: block; */
+.elgg-gallery .elgg-avatar > a > img {
+ display: inline-block;
+}
+.elgg-gallery .elgg-avatar > .elgg-icon-hover-menu {
+ bottom: 4px;
+}
diff --git a/views/default/css/ie7.php b/views/default/css/ie7.php
index 229df8431..90274797d 100644
--- a/views/default/css/ie7.php
+++ b/views/default/css/ie7.php
@@ -24,6 +24,7 @@
.elgg-menu-footer > li > a,
.elgg-menu-footer li,
.elgg-menu-general > li > a,
+.elgg-pagination li,
.elgg-menu-general li {
display: inline;
}
diff --git a/views/default/forms/plugins/settings/save.php b/views/default/forms/plugins/settings/save.php
index dc7b2fef7..116529905 100644
--- a/views/default/forms/plugins/settings/save.php
+++ b/views/default/forms/plugins/settings/save.php
@@ -17,11 +17,11 @@ if ($type != 'user') {
$type = '';
}
-if (elgg_view_exists("{$type}settings/$plugin_id/edit")) {
+if (elgg_view_exists("plugins/$plugin_id/{$type}settings")) {
+ echo elgg_view("plugins/$plugin_id/{$type}settings", $vars);
+} elseif (elgg_view_exists("{$type}settings/$plugin_id/edit")) {
elgg_deprecated_notice("{$type}settings/$plugin_id/edit was deprecated in favor of plugins/$plugin_id/{$type}settings", 1.8);
echo elgg_view("{$type}settings/$plugin_id/edit", $vars);
-} else {
- echo elgg_view("plugins/$plugin_id/{$type}settings", $vars);
}
echo '<div class="elgg-foot">';
diff --git a/views/default/forms/profile/edit.php b/views/default/forms/profile/edit.php
index 9538b779e..cb0a37ca4 100644
--- a/views/default/forms/profile/edit.php
+++ b/views/default/forms/profile/edit.php
@@ -13,6 +13,8 @@
</div>
<?php
+$sticky_values = elgg_get_sticky_values('profile:edit');
+
$profile_fields = elgg_get_config('profile_fields');
if (is_array($profile_fields) && count($profile_fields) > 0) {
foreach ($profile_fields as $shortname => $valtype) {
@@ -40,6 +42,14 @@ if (is_array($profile_fields) && count($profile_fields) > 0) {
$access_id = ACCESS_DEFAULT;
}
+ // sticky form values take precedence over saved ones
+ if (isset($sticky_values[$shortname])) {
+ $value = $sticky_values[$shortname];
+ }
+ if (isset($sticky_values['accesslevel'][$shortname])) {
+ $access_id = $sticky_values['accesslevel'][$shortname];
+ }
+
?>
<div>
<label><?php echo elgg_echo("profile:{$shortname}") ?></label>
@@ -59,6 +69,9 @@ if (is_array($profile_fields) && count($profile_fields) > 0) {
<?php
}
}
+
+elgg_clear_sticky_form('profile:edit');
+
?>
<div class="elgg-foot">
<?php
diff --git a/views/default/icon/default.php b/views/default/icon/default.php
index 087c7eae9..7f13a1189 100644
--- a/views/default/icon/default.php
+++ b/views/default/icon/default.php
@@ -37,13 +37,31 @@ if (isset($vars['href'])) {
$icon_sizes = elgg_get_config('icon_sizes');
$size = $vars['size'];
-$img = elgg_view('output/img', array(
+if (!isset($vars['width'])) {
+ $vars['width'] = $size != 'master' ? $icon_sizes[$size]['w'] : null;
+}
+if (!isset($vars['height'])) {
+ $vars['height'] = $size != 'master' ? $icon_sizes[$size]['h'] : null;
+}
+
+$img_params = array(
'src' => $entity->getIconURL($vars['size']),
- 'alt' => $title,
- 'class' => $class,
- 'width' => $size != 'master' ? $icon_sizes[$size]['w'] : NULL,
- 'height' => $size != 'master' ? $icon_sizes[$size]['h'] : NULL,
-));
+ 'alt' => $title,
+);
+
+if (!empty($class)) {
+ $img_params['class'] = $class;
+}
+
+if (!empty($vars['width'])) {
+ $img_params['width'] = $vars['width'];
+}
+
+if (!empty($vars['height'])) {
+ $img_params['height'] = $vars['height'];
+}
+
+$img = elgg_view('output/img', $img_params);
if ($url) {
$params = array(
diff --git a/views/default/input/userpicker.php b/views/default/input/userpicker.php
index 91a397e37..8b64d7df5 100644
--- a/views/default/input/userpicker.php
+++ b/views/default/input/userpicker.php
@@ -63,11 +63,13 @@ foreach ($vars['value'] as $user_id) {
?>
<div class="elgg-user-picker">
<input type="text" class="elgg-input-user-picker" size="30"/>
- <input type="checkbox" name="match_on" value="true" />
- <label><?php echo elgg_echo('userpicker:only_friends'); ?></label>
+ <label>
+ <input type="checkbox" name="match_on" value="true" />
+ <?php echo elgg_echo('userpicker:only_friends'); ?>
+ </label>
<ul class="elgg-user-picker-list"><?php echo $user_list; ?></ul>
</div>
<script type="text/javascript">
// @todo grab the values in the init function rather than using inline JS
elgg.userpicker.userList = <?php echo $json_values ?>;
-</script> \ No newline at end of file
+</script>
diff --git a/views/default/js/elgg.php b/views/default/js/elgg.php
index 6fe03484d..c3b56e398 100644
--- a/views/default/js/elgg.php
+++ b/views/default/js/elgg.php
@@ -43,7 +43,7 @@ $libs = array(
foreach ($libs as $file) {
include("{$CONFIG->path}js/lib/$file.js");
- // putting a new line between the files to address http://trac.elgg.org/ticket/3081
+ // putting a new line between the files to address https://github.com/elgg/elgg/issues/3081
echo "\n";
}
diff --git a/views/default/js/languages.php b/views/default/js/languages.php
index c51d7bcb2..fcf903d4b 100644
--- a/views/default/js/languages.php
+++ b/views/default/js/languages.php
@@ -1,15 +1,33 @@
<?php
/**
* @uses $vars['language']
+ * @uses $vars['lc'] if present, client will be sent long expires headers
*/
-global $CONFIG;
$language = $vars['language'];
+$lastcache = elgg_extract('lc', $vars, 0);
-$translations = $CONFIG->translations['en'];
+// @todo add server-side caching
+if ($lastcache) {
+ // we're relying on lastcache changes to predict language changes
+ $etag = '"' . md5("$language|$lastcache") . '"';
+
+ header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', strtotime("+6 months")), true);
+ header("Pragma: public", true);
+ header("Cache-Control: public", true);
+ header("ETag: $etag");
+
+ if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && trim($_SERVER['HTTP_IF_NONE_MATCH']) === $etag) {
+ header("HTTP/1.1 304 Not Modified");
+ exit;
+ }
+}
+
+$all_translations = elgg_get_config('translations');
+$translations = $all_translations['en'];
if ($language != 'en') {
- $translations = array_merge($translations, $CONFIG->translations[$language]);
+ $translations = array_merge($translations, $all_translations[$language]);
}
echo json_encode($translations); \ No newline at end of file
diff --git a/views/default/js/walled_garden.php b/views/default/js/walled_garden.php
index 7a482fe23..e228df507 100644
--- a/views/default/js/walled_garden.php
+++ b/views/default/js/walled_garden.php
@@ -5,12 +5,11 @@
* @since 1.8
*/
-// note that this assumes the button view is not using single quotes
$cancel_button = elgg_view('input/button', array(
'value' => elgg_echo('cancel'),
'class' => 'elgg-button-cancel mlm',
));
-$cancel_button = trim($cancel_button);
+$cancel_button = json_encode($cancel_button);
if (0) { ?><script><?php }
?>
@@ -23,10 +22,11 @@ elgg.walled_garden.init = function () {
$('.registration_link').click(elgg.walled_garden.load('register'));
$('input.elgg-button-cancel').live('click', function(event) {
- if ($('.elgg-walledgarden-single').is(':visible')) {
+ var $wgs = $('.elgg-walledgarden-single');
+ if ($wgs.is(':visible')) {
$('.elgg-walledgarden-double').fadeToggle();
- $('.elgg-walledgarden-single').fadeToggle();
- $('.elgg-walledgarden-single').remove();
+ $wgs.fadeToggle();
+ $wgs.remove();
}
event.preventDefault();
});
@@ -42,12 +42,22 @@ elgg.walled_garden.load = function(view) {
return function(event) {
var id = '#elgg-walledgarden-' + view;
id = id.replace('_', '-');
+ //@todo display some visual element that indicates that loading of content is running
elgg.get('walled_garden/' + view, {
'success' : function(data) {
- $('.elgg-body-walledgarden').append(data);
- $(id).find('input.elgg-button-submit').after('<?php echo $cancel_button; ?>');
- $('#elgg-walledgarden-login').fadeToggle();
- $(id).fadeToggle();
+ var $wg = $('.elgg-body-walledgarden');
+ $wg.append(data);
+ $(id).find('input.elgg-button-submit').after(<?php echo $cancel_button; ?>);
+
+ if (view == 'register' && $wg.hasClass('hidden')) {
+ // this was a failed register, display the register form ASAP
+ $('#elgg-walledgarden-login').toggle(false);
+ $(id).toggle();
+ $wg.removeClass('hidden');
+ } else {
+ $('#elgg-walledgarden-login').fadeToggle();
+ $(id).fadeToggle();
+ }
}
});
event.preventDefault();
diff --git a/views/default/object/default.php b/views/default/object/default.php
index 110648304..70e098742 100644
--- a/views/default/object/default.php
+++ b/views/default/object/default.php
@@ -41,7 +41,6 @@ $params = array(
'title' => $title,
'metadata' => $metadata,
'subtitle' => $subtitle,
- 'tags' => $vars['entity']->tags,
);
$params = $params + $vars;
$body = elgg_view('object/elements/summary', $params);
diff --git a/views/default/object/elements/full.php b/views/default/object/elements/full.php
index 9b89f9706..b4634fe7e 100644
--- a/views/default/object/elements/full.php
+++ b/views/default/object/elements/full.php
@@ -22,9 +22,9 @@ $summary = elgg_extract('summary', $vars);
$body = elgg_extract('body', $vars);
$class = elgg_extract('class', $vars);
if ($class) {
- $class = "elgg-content $class";
+ $class = "elgg-content clearfix $class";
} else {
- $class = "elgg-content";
+ $class = "elgg-content clearfix";
}
$header = elgg_view_image_block($icon, $summary);
diff --git a/views/default/object/elements/summary.php b/views/default/object/elements/summary.php
index c0f3ad340..63ab8f816 100644
--- a/views/default/object/elements/summary.php
+++ b/views/default/object/elements/summary.php
@@ -27,7 +27,7 @@ if ($title_link === '') {
$text = $entity->name;
}
$params = array(
- 'text' => $text,
+ 'text' => elgg_get_excerpt($text, 100),
'href' => $entity->getURL(),
'is_trusted' => true,
);
diff --git a/views/default/output/access.php b/views/default/output/access.php
index 91c5c721e..5c8d62c4d 100644
--- a/views/default/output/access.php
+++ b/views/default/output/access.php
@@ -11,7 +11,7 @@ if (isset($vars['entity']) && elgg_instanceof($vars['entity'])) {
$access_id = $vars['entity']->access_id;
$access_class = 'elgg-access';
$access_id_string = get_readable_access_level($access_id);
- $access_id_string = htmlentities($access_id_string, ENT_QUOTES, 'UTF-8');
+ $access_id_string = htmlspecialchars($access_id_string, ENT_QUOTES, 'UTF-8', false);
// if within a group or shared access collection display group name and open/closed membership status
// @todo have a better way to do this instead of checking against subtype / class.
diff --git a/views/default/output/tag.php b/views/default/output/tag.php
index 3e1f1c320..6bd9a72a7 100644
--- a/views/default/output/tag.php
+++ b/views/default/output/tag.php
@@ -8,25 +8,25 @@
*
*/
+if (!empty($vars['type'])) {
+ $type = "&type=" . rawurlencode($vars['type']);
+} else {
+ $type = "";
+}
if (!empty($vars['subtype'])) {
- $subtype = "&subtype=" . urlencode($vars['subtype']);
+ $subtype = "&subtype=" . rawurlencode($vars['subtype']);
} else {
$subtype = "";
}
if (!empty($vars['object'])) {
- $object = "&object=" . urlencode($vars['object']);
+ $object = "&object=" . rawurlencode($vars['object']);
} else {
$object = "";
}
if (isset($vars['value'])) {
+ $url = elgg_get_site_url() . 'search?q=' . rawurlencode($vars['value']) . "&search_type=tags{$type}{$subtype}{$object}";
$vars['value'] = htmlspecialchars($vars['value'], ENT_QUOTES, 'UTF-8', false);
- if (!empty($vars['type'])) {
- $type = "&type={$vars['type']}";
- } else {
- $type = "";
- }
- $url = elgg_get_site_url() . 'search?q=' . urlencode($vars['value']) . "&search_type=tags{$type}{$subtype}{$object}";
echo elgg_view('output/url', array(
'href' => $url,
'text' => $vars['value'],
diff --git a/views/default/output/tags.php b/views/default/output/tags.php
index 41fd5f168..db096a3be 100644
--- a/views/default/output/tags.php
+++ b/views/default/output/tags.php
@@ -17,13 +17,18 @@ if (isset($vars['entity'])) {
unset($vars['entity']);
}
+if (!empty($vars['type'])) {
+ $type = "&type=" . rawurlencode($vars['type']);
+} else {
+ $type = "";
+}
if (!empty($vars['subtype'])) {
- $subtype = "&subtype=" . urlencode($vars['subtype']);
+ $subtype = "&subtype=" . rawurlencode($vars['subtype']);
} else {
$subtype = "";
}
if (!empty($vars['object'])) {
- $object = "&object=" . urlencode($vars['object']);
+ $object = "&object=" . rawurlencode($vars['object']);
} else {
$object = "";
}
@@ -53,16 +58,11 @@ if (!empty($vars['tags'])) {
$icon_class = elgg_extract('icon_class', $vars);
$list_items = '<li>' . elgg_view_icon('tag', $icon_class) . '</li>';
-
+
foreach($vars['tags'] as $tag) {
- $tag = htmlspecialchars($tag, ENT_QUOTES, 'UTF-8', false);
- if (!empty($vars['type'])) {
- $type = "&type={$vars['type']}";
- } else {
- $type = "";
- }
- $url = elgg_get_site_url() . 'search?q=' . urlencode($tag) . "&search_type=tags{$type}{$subtype}{$object}";
+ $url = elgg_get_site_url() . 'search?q=' . rawurlencode($tag) . "&search_type=tags{$type}{$subtype}{$object}";
if (is_string($tag)) {
+ $tag = htmlspecialchars($tag, ENT_QUOTES, 'UTF-8', false);
$list_items .= "<li class=\"$item_class\">";
$list_items .= elgg_view('output/url', array('href' => $url, 'text' => $tag, 'rel' => 'tag'));
$list_items .= '</li>';
diff --git a/views/default/page/walled_garden.php b/views/default/page/walled_garden.php
index ff8e317c7..b280cf6b2 100644
--- a/views/default/page/walled_garden.php
+++ b/views/default/page/walled_garden.php
@@ -5,6 +5,12 @@
* Used for the walled garden index page
*/
+$is_sticky_register = elgg_is_sticky_form('register');
+$wg_body_class = 'elgg-body-walledgarden';
+if ($is_sticky_register) {
+ $wg_body_class .= ' hidden';
+}
+
// Set the content type
header("Content-type: text/html; charset=UTF-8");
?>
@@ -18,10 +24,17 @@ header("Content-type: text/html; charset=UTF-8");
<div class="elgg-page-messages">
<?php echo elgg_view('page/elements/messages', array('object' => $vars['sysmessages'])); ?>
</div>
- <div class="elgg-body-walledgarden">
+ <div class="<?php echo $wg_body_class; ?>">
<?php echo $vars['body']; ?>
</div>
</div>
+<?php if ($is_sticky_register): ?>
+<script type="text/javascript">
+elgg.register_hook_handler('init', 'system', function() {
+ $('.registration_link').trigger('click');
+});
+</script>
+<?php endif; ?>
<?php echo elgg_view('page/elements/foot'); ?>
</body>
</html> \ No newline at end of file
diff --git a/views/default/river/elements/summary.php b/views/default/river/elements/summary.php
index 416bc708b..d7bde51dd 100644
--- a/views/default/river/elements/summary.php
+++ b/views/default/river/elements/summary.php
@@ -18,9 +18,10 @@ $subject_link = elgg_view('output/url', array(
'is_trusted' => true,
));
+$object_text = $object->title ? $object->title : $object->name;
$object_link = elgg_view('output/url', array(
'href' => $object->getURL(),
- 'text' => $object->title ? $object->title : $object->name,
+ 'text' => elgg_get_excerpt($object_text, 100),
'class' => 'elgg-river-object',
'is_trusted' => true,
));