aboutsummaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engine')
-rw-r--r--engine/classes/ElggFile.php41
-rw-r--r--engine/classes/ElggPlugin.php22
-rw-r--r--engine/classes/ElggPluginPackage.php2
-rw-r--r--engine/lib/access.php2
-rw-r--r--engine/lib/annotations.php2
-rw-r--r--engine/lib/configuration.php9
-rw-r--r--engine/lib/database.php23
-rw-r--r--engine/lib/elgglib.php3
-rw-r--r--engine/lib/entities.php2
-rw-r--r--engine/lib/metadata.php2
-rw-r--r--engine/lib/navigation.php10
-rw-r--r--engine/lib/relationships.php2
-rw-r--r--engine/lib/views.php13
-rw-r--r--engine/tests/regression/trac_bugs.php87
-rw-r--r--engine/tests/suite.php2
15 files changed, 191 insertions, 31 deletions
diff --git a/engine/classes/ElggFile.php b/engine/classes/ElggFile.php
index fe25491a8..f21621ffd 100644
--- a/engine/classes/ElggFile.php
+++ b/engine/classes/ElggFile.php
@@ -121,6 +121,47 @@ class ElggFile extends ElggObject {
}
/**
+ * Detects mime types based on filename or actual file.
+ *
+ * @param mixed $file The full path of the file to check. For uploaded files, use tmp_name.
+ * @param mixed $default A default. Useful to pass what the browser thinks it is.
+ * @since 1.7.12
+ *
+ * @return mixed Detected type on success, false on failure.
+ */
+ static function detectMimeType($file = null, $default = null) {
+ if (!$file) {
+ if (isset($this) && $this->filename) {
+ $file = $this->filename;
+ } else {
+ return false;
+ }
+ }
+
+ $mime = false;
+
+ // for PHP5 folks.
+ if (function_exists('finfo_file') && defined('FILEINFO_MIME_TYPE')) {
+ $resource = finfo_open(FILEINFO_MIME_TYPE);
+ if ($resource) {
+ $mime = finfo_file($resource, $file);
+ }
+ }
+
+ // for everyone else.
+ if (!$mime && function_exists('mime_content_type')) {
+ $mime = mime_content_type($file);
+ }
+
+ // default
+ if (!$mime) {
+ return $default;
+ }
+
+ return $mime;
+ }
+
+ /**
* Set the optional file description.
*
* @param string $description The description.
diff --git a/engine/classes/ElggPlugin.php b/engine/classes/ElggPlugin.php
index d837431fc..4aee1e898 100644
--- a/engine/classes/ElggPlugin.php
+++ b/engine/classes/ElggPlugin.php
@@ -116,6 +116,21 @@ class ElggPlugin extends ElggObject {
}
/**
+ * Returns the manifest's name if available, otherwise the ID.
+ *
+ * @return string
+ * @since 1.8.1
+ */
+ public function getFriendlyName() {
+ $manifest = $this->getManifest();
+ if ($manifest) {
+ return $manifest->getName();
+ }
+
+ return $this->getID();
+ }
+
+ /**
* Returns the plugin's full path with trailing slash.
*
* @return string
@@ -597,7 +612,12 @@ class ElggPlugin extends ElggObject {
*/
public function canActivate($site_guid = null) {
if ($this->getPackage()) {
- return $this->getPackage()->isValid() && $this->getPackage()->checkDependencies();
+ $result = $this->getPackage()->isValid() && $this->getPackage()->checkDependencies();
+ if (!$result) {
+ $this->errorMsg = $this->getPackage()->getError();
+ }
+
+ return $result;
}
return false;
diff --git a/engine/classes/ElggPluginPackage.php b/engine/classes/ElggPluginPackage.php
index 02b985285..145f71fcd 100644
--- a/engine/classes/ElggPluginPackage.php
+++ b/engine/classes/ElggPluginPackage.php
@@ -347,6 +347,7 @@ class ElggPluginPackage {
$conflict['name'] = $plugin->getManifest()->getName();
if (!$full_report && !$result['status']) {
+ $this->errorMsg = "Conflicts with plugin \"{$plugin->getManifest()->getName()}\".";
return $result['status'];
} else {
$report[] = array(
@@ -399,6 +400,7 @@ class ElggPluginPackage {
// unless we're doing a full report, break as soon as we fail.
if (!$full_report && !$result['status']) {
+ $this->errorMsg = "Missing dependencies.";
return $result['status'];
} else {
// build report element and comment
diff --git a/engine/lib/access.php b/engine/lib/access.php
index 20f57ec41..1fe21861d 100644
--- a/engine/lib/access.php
+++ b/engine/lib/access.php
@@ -776,7 +776,7 @@ function elgg_view_access_collections($owner_guid) {
* access_id => int The access ID of the entity.
*
* @see elgg_get_entities()
- * @return mixed int if count is true, an array of entity objects, or false on failure
+ * @return mixed if count, int. if not count, array or false if no entities. false also on errors.
* @since 1.7.0
*/
function elgg_get_entities_from_access_id(array $options = array()) {
diff --git a/engine/lib/annotations.php b/engine/lib/annotations.php
index 9ab5a1b39..14893aee6 100644
--- a/engine/lib/annotations.php
+++ b/engine/lib/annotations.php
@@ -319,7 +319,7 @@ function elgg_list_annotations($options) {
*
* annotation_ids => NULL|ARR Annotation IDs
*
- * @return mixed int if count is true, an array of entity objects, or false on failure
+ * @return mixed if count, int. if not count, array or false if no entities. false also on errors.
* @since 1.7.0
*/
function elgg_get_entities_from_annotations(array $options = array()) {
diff --git a/engine/lib/configuration.php b/engine/lib/configuration.php
index b756d2e70..3a2364057 100644
--- a/engine/lib/configuration.php
+++ b/engine/lib/configuration.php
@@ -464,11 +464,6 @@ function get_config($name, $site_guid = 0) {
$dep_version = 1.8;
break;
- case 'wwwroot':
- $new_name = 'www_root';
- $dep_version = 1.8;
- break;
-
case 'sitename':
$new_name = 'site_name';
$dep_version = 1.8;
@@ -553,7 +548,7 @@ function set_default_config() {
'path' => "$install_root/",
'view_path' => "$install_root/views/",
'plugins_path' => "$install_root/mod/",
- 'www_root' => $www_root,
+ 'wwwroot' => $www_root,
'url' => $www_root,
'site_name' => 'New Elgg site',
'language' => 'en',
@@ -561,8 +556,6 @@ function set_default_config() {
// compatibility with old names for ppl not using get_config()
'viewpath' => "$install_root/views/",
'pluginspath' => "$install_root/mod/",
- 'wwwroot' => $www_root,
- 'url' => $www_root,
'sitename' => 'New Elgg site',
);
diff --git a/engine/lib/database.php b/engine/lib/database.php
index 7747eb0d5..f12b50079 100644
--- a/engine/lib/database.php
+++ b/engine/lib/database.php
@@ -163,10 +163,17 @@ function db_delayedexecution_shutdown_hook() {
global $DB_DELAYED_QUERIES;
foreach ($DB_DELAYED_QUERIES as $query_details) {
- // use one of our db functions so it is included in profiling.
- $result = execute_query($query_details['q'], $query_details['l']);
-
try {
+ $link = $query_details['l'];
+
+ if ($link == 'read' || $link == 'write') {
+ $link = get_db_link($link);
+ } elseif (!is_resource($link)) {
+ elgg_log("Link for delayed query not valid resource or db_link type. Query: {$query_details['q']}", 'WARNING');
+ }
+
+ $result = execute_query($query_details['q'], $link);
+
if ((isset($query_details['h'])) && (is_callable($query_details['h']))) {
$query_details['h']($result);
}
@@ -272,7 +279,7 @@ function execute_query($query, $dblink) {
* the raw result from {@link mysql_query()}.
*
* @param string $query The query to execute
- * @param resource $dblink The database link to use
+ * @param resource $dblink The database link to use or the link type (read | write)
* @param string $handler A callback function to pass the results array to
*
* @return true
@@ -284,6 +291,10 @@ function execute_delayed_query($query, $dblink, $handler = "") {
$DB_DELAYED_QUERIES = array();
}
+ if (!is_resource($dblink) && $dblink != 'read' && $dblink != 'write') {
+ return false;
+ }
+
// Construct delayed query
$delayed_query = array();
$delayed_query['q'] = $query;
@@ -306,7 +317,7 @@ function execute_delayed_query($query, $dblink, $handler = "") {
* @uses get_db_link()
*/
function execute_delayed_write_query($query, $handler = "") {
- return execute_delayed_query($query, get_db_link('write'), $handler);
+ return execute_delayed_query($query, 'write', $handler);
}
/**
@@ -320,7 +331,7 @@ function execute_delayed_write_query($query, $handler = "") {
* @uses get_db_link()
*/
function execute_delayed_read_query($query, $handler = "") {
- return execute_delayed_query($query, get_db_link('read'), $handler);
+ return execute_delayed_query($query, 'read', $handler);
}
/**
diff --git a/engine/lib/elgglib.php b/engine/lib/elgglib.php
index 7bdc5972a..c62175629 100644
--- a/engine/lib/elgglib.php
+++ b/engine/lib/elgglib.php
@@ -2031,7 +2031,10 @@ function elgg_init() {
elgg_register_js('elgg.userpicker', 'js/lib/userpicker.js');
elgg_register_js('elgg.friendspicker', 'js/lib/friends_picker.js');
elgg_register_js('jquery.easing', 'vendors/jquery/jquery.easing.1.3.packed.js');
+ elgg_register_js('jquery.imgareaselect', 'vendors/jquery/jquery.imgareaselect-0.9.8/scripts/jquery.imgareaselect.min.js');
+ elgg_register_css('jquery.imgareaselect', 'vendors/jquery/jquery.imgareaselect-0.9.8/css/imgareaselect-deprecated.css');
+
// Trigger the shutdown:system event upon PHP shutdown.
register_shutdown_function('_elgg_shutdown_hook');
diff --git a/engine/lib/entities.php b/engine/lib/entities.php
index abf7395e7..c8317d64d 100644
--- a/engine/lib/entities.php
+++ b/engine/lib/entities.php
@@ -772,7 +772,7 @@ function elgg_entity_exists($guid) {
*
* callback => string A callback function to pass each row through
*
- * @return mixed int if count is true, an array of entity objects, or false on failure
+ * @return mixed if count, int. if not count, array or false if no entities. false also on errors.
* @since 1.7.0
* @see elgg_get_entities_from_metadata()
* @see elgg_get_entities_from_relationship()
diff --git a/engine/lib/metadata.php b/engine/lib/metadata.php
index 2becc5f3c..e5389df38 100644
--- a/engine/lib/metadata.php
+++ b/engine/lib/metadata.php
@@ -397,7 +397,7 @@ function elgg_enable_metadata(array $options) {
*
* metadata_owner_guids => NULL|ARR guids for metadata owners
*
- * @return mixed int if count is true, an array of entity objects, or false on failure
+ * @return mixed if count, int. if not count, array or false if no entities. false also on errors.
* @since 1.7.0
*/
function elgg_get_entities_from_metadata(array $options = array()) {
diff --git a/engine/lib/navigation.php b/engine/lib/navigation.php
index 27af26be2..3f3a8ecd5 100644
--- a/engine/lib/navigation.php
+++ b/engine/lib/navigation.php
@@ -20,20 +20,20 @@
* Menus
* Elgg uses a single interface to manage its menus. Menu items are added with
* {@link elgg_register_menu_item()}. This is generally used for menus that
- * appear only once per page. For context-sensitive menus (such as the hover
+ * appear only once per page. For dynamic menus (such as the hover
* menu for user's avatar), a plugin hook is emitted when the menu is being
* created. The hook is 'register', 'menu:<menu_name>'. For more details on this,
* @see elgg_view_menu().
*
* Menus supported by the Elgg core
* Standard menus:
- * site Site navihgation shown on every page.
+ * site Site navigation shown on every page.
* page Page menu usually shown in a sidebar. Uses Elgg's context.
* topbar Topbar menu shown on every page. The default has two sections.
* footer Like the topbar but in the footer.
* extras Links about content on the page. The RSS link is added to this.
*
- * Context-sensitive (also called just-in-time menus):
+ * Dynamic menus (also called just-in-time menus):
* user_hover Avatar hover menu. The user entity is passed as a parameter.
* entity The set of links shown in the summary of an entity.
* river Links shown on river items.
@@ -51,7 +51,7 @@
*
* @warning Generally you should not use this in response to the plugin hook:
* 'register', 'menu:<menu_name>'. If you do, you may end up with many incorrect
- * links on a context-sensitive menu.
+ * links on a dynamic menu.
*
* @warning A menu item's name must be unique per menu. If more than one menu
* item with the same name are registered, the last menu item takes priority.
@@ -393,7 +393,7 @@ function elgg_annotation_menu_setup($hook, $type, $return, $params) {
'href' => $url,
'text' => "<span class=\"elgg-icon elgg-icon-delete\"></span>",
'confirm' => elgg_echo('deleteconfirm'),
- 'text_encode' => false
+ 'encode_text' => false
);
$return[] = ElggMenuItem::factory($options);
}
diff --git a/engine/lib/relationships.php b/engine/lib/relationships.php
index f1da65a34..ede5ca1eb 100644
--- a/engine/lib/relationships.php
+++ b/engine/lib/relationships.php
@@ -249,7 +249,7 @@ function get_entity_relationships($guid, $inverse_relationship = FALSE) {
*
* inverse_relationship => BOOL Inverse the relationship
*
- * @return mixed int if count is true, an array of entity objects, or false on failure
+ * @return mixed if count, int. if not count, array or false if no entities. false also on errors.
* @since 1.7.0
*/
function elgg_get_entities_from_relationship($options) {
diff --git a/engine/lib/views.php b/engine/lib/views.php
index c31f61e84..a18118f32 100644
--- a/engine/lib/views.php
+++ b/engine/lib/views.php
@@ -709,9 +709,9 @@ function elgg_view_layout($layout_name, $vars = array()) {
*
* This function triggers a 'register', 'menu:<menu name>' plugin hook that enables
* plugins to add menu items just before a menu is rendered. This is used by
- * context-sensitive menus (menus that are specific to a particular entity such
- * as the user hover menu). Using elgg_register_menu_item() in response to the hook
- * can cause incorrect links to show up. See the blog plugin's blog_owner_block_menu()
+ * dynamic menus (menus that change based on some input such as the user hover
+ * menu). Using elgg_register_menu_item() in response to the hook can cause
+ * incorrect links to show up. See the blog plugin's blog_owner_block_menu()
* for an example of using this plugin hook.
*
* An additional hook is the 'prepare', 'menu:<menu name>' which enables plugins
@@ -724,8 +724,9 @@ function elgg_view_layout($layout_name, $vars = array()) {
* @param array $vars An associative array of display options for the menu.
* Options include:
* sort_by => string or php callback
- * string options: 'name', 'priority', 'title' (default), 'register' (registration order)
- * php callback: a compare function for usort
+ * string options: 'name', 'priority', 'title' (default),
+ * 'register' (registration order) or a
+ * php callback (a compare function for usort)
* handler: string the page handler to build action URLs
* entity: ElggEntity to use to build action URLs
* class: string the class for the entire menu.
@@ -744,7 +745,7 @@ function elgg_view_menu($menu_name, array $vars = array()) {
$menu = $CONFIG->menus[$menu_name];
// Give plugins a chance to add menu items just before creation.
- // This supports context sensitive menus (ex. user_hover).
+ // This supports dynamic menus (example: user_hover).
$menu = elgg_trigger_plugin_hook('register', "menu:$menu_name", $vars, $menu);
$builder = new ElggMenuBuilder($menu);
diff --git a/engine/tests/regression/trac_bugs.php b/engine/tests/regression/trac_bugs.php
index 6f98c67bd..23d6d1dc6 100644
--- a/engine/tests/regression/trac_bugs.php
+++ b/engine/tests/regression/trac_bugs.php
@@ -112,4 +112,91 @@ class ElggCoreRegressionBugsTest extends ElggCoreUnitTest {
$this->assertEqual($params['xoffset'], $options['x1']);
$this->assertEqual($params['yoffset'], $options['y1']);
}
+
+ // #3722 Check canEdit() works for contains regardless of groups
+ function test_can_write_to_container() {
+ $user = new ElggUser();
+ $user->username = 'test_user_' . rand();
+ $user->name = 'test_user_name_' . rand();
+ $user->email = 'test@user.net';
+ $user->container_guid = 0;
+ $user->owner_guid = 0;
+ $user->save();
+
+ $object = new ElggObject();
+ $object->save();
+
+ $group = new ElggGroup();
+ $group->save();
+
+ // disable access overrides because we're admin.
+ $ia = elgg_set_ignore_access(false);
+
+ $this->assertFalse(can_write_to_container($user->guid, $object->guid));
+
+ global $elgg_test_user;
+ $elgg_test_user = $user;
+
+ // register hook to allow access
+ function can_write_to_container_test_hook($hook, $type, $value, $params) {
+ global $elgg_test_user;
+
+ if ($params['user']->getGUID() == $elgg_test_user->getGUID()) {
+ return true;
+ }
+ }
+
+ register_plugin_hook('container_permissions_check', 'all', 'can_write_to_container_test_hook');
+ $this->assertTrue(can_write_to_container($user->guid, $object->guid));
+ unregister_plugin_hook('container_permissions_check', 'all', 'can_write_to_container_test_hook');
+
+ $this->assertFalse(can_write_to_container($user->guid, $group->guid));
+ $group->join($user);
+ $this->assertTrue(can_write_to_container($user->guid, $group->guid));
+
+ elgg_set_ignore_access($ia);
+
+ $user->delete();
+ $object->delete();
+ $group->delete();
+ }
+
+ function test_db_shutdown_links() {
+ global $DB_DELAYED_QUERIES, $test_results;
+ $DB_DELAYED_QUERIES = array();
+
+ function test_delayed_results($results) {
+ global $test_results;
+ $test_results = $results;
+ }
+
+ $q = 'SELECT 1 as test';
+
+ $links = array('read', 'write', get_db_link('read'), get_db_link('write'));
+
+ foreach ($links as $link) {
+ $DB_DELAYED_QUERIES = array();
+
+ $result = execute_delayed_query($q, $link, 'test_delayed_results');
+
+ $this->assertTrue($result, "Failed with link = $link");
+ $this->assertEqual(count($DB_DELAYED_QUERIES), 1);
+ $this->assertEqual($DB_DELAYED_QUERIES[0]['q'], $q);
+ $this->assertEqual($DB_DELAYED_QUERIES[0]['l'], $link);
+ $this->assertEqual($DB_DELAYED_QUERIES[0]['h'], 'test_delayed_results');
+
+ db_delayedexecution_shutdown_hook();
+
+ $num_rows = mysql_num_rows($test_results);
+ $this->assertEqual($num_rows, 1);
+ $row = mysql_fetch_assoc($test_results);
+ $this->assertEqual($row['test'], 1);
+ }
+
+ // test bad case
+ $DB_DELAYED_QUERIES = array();
+ $result = execute_delayed_query($q, 'not_a_link', 'test_delayed_results');
+ $this->assertFalse($result);
+ $this->assertEqual(array(), $DB_DELAYED_QUERIES);
+ }
}
diff --git a/engine/tests/suite.php b/engine/tests/suite.php
index 8f2eb41a3..4203bc5d6 100644
--- a/engine/tests/suite.php
+++ b/engine/tests/suite.php
@@ -9,6 +9,8 @@
require_once(dirname( __FILE__ ) . '/../start.php');
+admin_gatekeeper();
+
$vendor_path = "$CONFIG->path/vendors/simpletest";
$test_path = "$CONFIG->path/engine/tests";