/** * Process logging data * * @param mixed $data The data to process * @param bool $display Whether to display the data to the user. Otherwise log it. * @param int $level The logging level for this data * @return void */ protected function process($data, $display, $level) { // plugin can return false to stop the default logging method $params = array('level' => $level, 'msg' => $data, 'display' => $display, 'to_screen' => $display); if (!$this->hooks->trigger('debug', 'log', $params, true)) { return; } // Do not want to write to screen before page creation has started. // This is not fool-proof but probably fixes 95% of the cases when logging // results in data sent to the browser before the page is begun. if (!isset($this->CONFIG->pagesetupdone)) { $display = false; } // Do not want to write to JS or CSS pages if (elgg_in_context('js') || elgg_in_context('css')) { $display = false; } if ($display == true) { echo '<pre class="elgg-logger-data">'; echo htmlspecialchars(print_r($data, true), ENT_QUOTES, 'UTF-8'); echo '</pre>'; } else { error_log(print_r($data, true)); } }
/** * @access private */ public function renderView($view, array $vars = array(), $bypass = false, $viewtype = '', $issue_missing_notice = true) { $view = $this->canonicalizeViewName($view); if (!is_string($view) || !is_string($viewtype)) { $this->logger->log("View and Viewtype in views must be a strings: {$view}", 'NOTICE'); return ''; } // basic checking for bad paths if (strpos($view, '..') !== false) { return ''; } if (!is_array($vars)) { $this->logger->log("Vars in views must be an array: {$view}", 'ERROR'); $vars = array(); } // Get the current viewtype if ($viewtype === '' || !_elgg_is_valid_viewtype($viewtype)) { $viewtype = elgg_get_viewtype(); } // allow altering $vars $vars_hook_params = ['view' => $view, 'vars' => $vars, 'viewtype' => $viewtype]; $vars = $this->hooks->trigger('view_vars', $view, $vars_hook_params, $vars); $view_orig = $view; // Trigger the pagesetup event if (!isset($GLOBALS['_ELGG']->pagesetupdone) && !empty($this->CONFIG->boot_complete)) { $GLOBALS['_ELGG']->pagesetupdone = true; _elgg_services()->events->trigger('pagesetup', 'system'); } // Set up any extensions to the requested view if (isset($this->views->extensions[$view])) { $viewlist = $this->views->extensions[$view]; } else { $viewlist = array(500 => $view); } $content = ''; foreach ($viewlist as $view) { $rendering = $this->renderViewFile($view, $vars, $viewtype, $issue_missing_notice); if ($rendering !== false) { $content .= $rendering; continue; } // attempt to load default view if ($viewtype !== 'default' && $this->doesViewtypeFallback($viewtype)) { $rendering = $this->renderViewFile($view, $vars, 'default', $issue_missing_notice); if ($rendering !== false) { $content .= $rendering; } } } // Plugin hook $params = array('view' => $view_orig, 'vars' => $vars, 'viewtype' => $viewtype); $content = $this->hooks->trigger('view', $view_orig, $params, $content); return $content; }
/** * Split a menu into sections, and pass it through the "prepare" hook * * @param UnpreparedMenu $menu Menu * * @return Menu */ public function prepareMenu(UnpreparedMenu $menu) { $name = $menu->getName(); $params = $menu->getParams(); $sort_by = $menu->getSortBy(); $builder = new ElggMenuBuilder($menu->getItems()); $params['menu'] = $builder->getMenu($sort_by); $params['selected_item'] = $builder->getSelected(); $params['menu'] = $this->hooks->trigger('prepare', "menu:{$name}", $params, $params['menu']); return new Menu($params); }
/** * Filter an AjaxResponse through a plugin hook * * @param AjaxResponse $api_response The API Response * @param string $hook_type The hook type. If given, the response will be filtered by hook * * @return AjaxResponse */ private function filterApiResponse(AjaxResponse $api_response, $hook_type = '') { $api_response->setTtl($this->input->get('response_ttl', 0, false)); if ($hook_type) { $hook = AjaxResponse::RESPONSE_HOOK; $api_response = $this->hooks->trigger($hook, $hook_type, null, $api_response); if (!$api_response instanceof AjaxResponse) { throw new \RuntimeException("The value returned by hook [{$hook}, {$hook_type}] was not an ApiResponse"); } } return $api_response; }
/** * Is someone using the deprecated override * * @param \Elgg\Notifications\Event $event Event * @return boolean */ protected function existsDeprecatedNotificationOverride(\Elgg\Notifications\Event $event) { $entity = $event->getObject(); if (!elgg_instanceof($entity)) { return false; } $params = array('event' => $event->getAction(), 'object_type' => $entity->getType(), 'object' => $entity); $hookresult = $this->hooks->trigger('object:notifications', $entity->getType(), $params, false); if ($hookresult === true) { elgg_deprecated_notice("Using the plugin hook 'object:notifications' has been deprecated by the hook 'send:before', 'notifications'", 1.9); return true; } else { return false; } }
/** * @access private */ public function renderView($view, array $vars = [], $ignored = false, $viewtype = '', $issue_missing_notice = true) { $view = $this->canonicalizeViewName($view); if (!is_string($view) || !is_string($viewtype)) { $this->logger->log("View and Viewtype in views must be a strings: {$view}", 'NOTICE'); return ''; } // basic checking for bad paths if (strpos($view, '..') !== false) { return ''; } if (!is_array($vars)) { $this->logger->log("Vars in views must be an array: {$view}", 'ERROR'); $vars = array(); } // Get the current viewtype if ($viewtype === '' || !_elgg_is_valid_viewtype($viewtype)) { $viewtype = elgg_get_viewtype(); } // allow altering $vars $vars_hook_params = ['view' => $view, 'vars' => $vars, 'viewtype' => $viewtype]; $vars = $this->hooks->trigger(self::VIEW_VARS_HOOK, $view, $vars_hook_params, $vars); // allow $vars to hijack output if (isset($vars[self::OUTPUT_KEY])) { return (string) $vars[self::OUTPUT_KEY]; } $view_orig = $view; $viewlist = $this->getViewList($view); $content = ''; foreach ($viewlist as $view) { $rendering = $this->renderViewFile($view, $vars, $viewtype, $issue_missing_notice); if ($rendering !== false) { $content .= $rendering; continue; } // attempt to load default view if ($viewtype !== 'default' && $this->doesViewtypeFallback($viewtype)) { $rendering = $this->renderViewFile($view, $vars, 'default', $issue_missing_notice); if ($rendering !== false) { $content .= $rendering; } } } // Plugin hook $params = ['view' => $view_orig, 'vars' => $vars, 'viewtype' => $viewtype]; $content = $this->hooks->trigger(self::VIEW_HOOK, $view_orig, $params, $content); return $content; }
/** * Get the notification body using a pre-Elgg 1.9 plugin hook * * @param Notification $notification Notification * @param NotificationEvent $event Event * @param string $method Method * @return Notification */ protected function getDeprecatedNotificationBody(Notification $notification, NotificationEvent $event, $method) { $entity = $event->getObject(); if (!$entity) { return $notification; } $params = array('entity' => $entity, 'to_entity' => $notification->getRecipient(), 'method' => $method); $subject = $this->getDeprecatedNotificationSubject($entity->getType(), $entity->getSubtype()); $string = $subject . ": " . $entity->getURL(); $body = $this->hooks->trigger('notify:entity:message', $entity->getType(), $params, $string); if ($subject) { $notification->subject = $subject; $notification->body = $body; } return $notification; }
/** * Removes a user from an access collection. * * Triggers the 'access:collections:remove_user', 'collection' plugin hook. * * @param int $user_guid The user GUID * @param int $collection_id The access collection ID * * @return bool */ function removeUser($user_guid, $collection_id) { $collection_id = (int) $collection_id; $user_guid = (int) $user_guid; $user = get_user($user_guid); $collection = $this->get($collection_id); if (!$user instanceof ElggUser || !$collection) { return false; } $params = array('collection_id' => $collection_id, 'user_guid' => $user_guid); if (!$this->hooks->trigger('access:collections:remove_user', 'collection', $params, true)) { return false; } $db = $this->db; $prefix = $db->prefix; $q = "DELETE FROM {$prefix}access_collection_membership\n\t\t\tWHERE access_collection_id = {$collection_id}\n\t\t\t\tAND user_guid = {$user_guid}"; return (bool) $db->deleteData($q); }
/** * Can a user annotate an entity? * * @tip Can be overridden by registering for the plugin hook [permissions_check:annotate:<name>, * <entity type>] or [permissions_check:annotate, <entity type>]. The hooks are called in that order. * * @tip If you want logged out users to annotate an object, do not call * canAnnotate(). It's easier than using the plugin hook. * * @param ElggEntity $entity Objet entity * @param int $user_guid User guid (default is logged in user) * @param string $annotation_name The name of the annotation (default is unspecified) * * @return bool */ public function canAnnotate(ElggEntity $entity, $user_guid = 0, $annotation_name = '') { if ($annotation_name === null || $annotation_name === false) { // accepting these for BC $annotation_name = ''; } elseif (!is_string($annotation_name)) { throw new InvalidArgumentException(__METHOD__ . ' expects \\$annotation_name to be a string'); } try { $user = $this->entities->getUserForPermissionsCheck($user_guid); } catch (UserFetchFailureException $e) { return false; } $return = (bool) $user; $params = ['entity' => $entity, 'user' => $user, 'annotation_name' => $annotation_name]; if (!empty($annotation_name)) { $return = $this->hooks->trigger("permissions_check:annotate:{$annotation_name}", $entity->getType(), $params, $return); } return $this->hooks->trigger('permissions_check:annotate', $entity->getType(), $params, $return); }
/** * Returns a configuration array of icon sizes * * @param string $entity_type Entity type * @param string $entity_subtype Entity subtype * @param string $type The name of the icon. e.g., 'icon', 'cover_photo' * @return array * @throws InvalidParameterException */ public function getSizes($entity_type = null, $entity_subtype = null, $type = 'icon') { $sizes = []; if (!$type) { $type = 'icon'; } if ($type == 'icon') { $sizes = $this->config->get('icon_sizes'); } $params = ['type' => $type, 'entity_type' => $entity_type, 'entity_subtype' => $entity_subtype]; if ($entity_type) { $sizes = $this->hooks->trigger("entity:{$type}:sizes", $entity_type, $params, $sizes); } if (!is_array($sizes)) { throw new InvalidParameterException("The icon size configuration for image type '{$type}' " . "must be an associative array of image size names and their properties"); } if (empty($sizes)) { $this->logger->error("Failed to find size configuration for image of type '{$type}' for entity type " . "'{$entity_type}'. Use the 'entity:{$type}:sizes, {$entity_type}' hook to define the icon sizes"); } return $sizes; }
/** * Prepares a redirect response * * @param string $forward_url Redirection URL * @param mixed $status_code HTTP status code or forward reason * @return SymfonyRedirectResponse * @throws InvalidParameterException */ public function redirect($forward_url = REFERRER, $status_code = ELGG_HTTP_FOUND) { if ($forward_url === REFERRER) { $forward_url = $this->request->headers->get('Referer'); } $forward_url = elgg_normalize_url($forward_url); // allow plugins to rewrite redirection URL $current_page = current_page_url(); $params = ['current_url' => $current_page, 'forward_url' => $forward_url]; $forward_reason = (string) $status_code; $forward_url = $this->hooks->trigger('forward', $forward_reason, $params, $forward_url); if ($this->response_sent) { // Response was sent from a forward hook // Clearing handlers to void infinite loops return $this->response_sent; } if ($forward_url === REFERRER) { $forward_url = $this->request->headers->get('Referer'); } if (!is_string($forward_url)) { throw new InvalidParameterException("'forward', '{$forward_reason}' hook must return a valid redirection URL"); } $forward_url = elgg_normalize_url($forward_url); switch ($status_code) { case 'system': case 'csrf': $status_code = ELGG_HTTP_OK; break; case 'admin': case 'login': case 'member': case 'walled_garden': default: $status_code = (int) $status_code; if (!$status_code || $status_code < 100 || $status_code > 599) { $status_code = ELGG_HTTP_SEE_OTHER; } break; } if ($this->isXhr()) { if ($status_code < 100 || $status_code >= 300 && $status_code <= 399 || $status_code > 599) { // We only want to preserve OK and error codes // Redirect responses should be converted to OK responses as this is an XHR request $status_code = ELGG_HTTP_OK; } $output = ob_get_clean(); if (!$this->isAction() && !$this->ajax->isAjax2Request()) { // legacy ajax calls are always OK // actions are wrapped by ResponseFactory::respond() $status_code = ELGG_HTTP_OK; $output = $this->wrapLegacyAjaxResponse($output, $forward_url); } $response = new OkResponse($output, $status_code, $forward_url); $headers = $response->getHeaders(); $headers['Content-Type'] = 'application/json; charset=UTF-8'; $response->setHeaders($headers); return $this->respond($response); } if ($this->isAction()) { // actions should always redirect on non xhr-calls if (!is_int($status_code) || $status_code < 300 || $status_code > 399) { $status_code = ELGG_HTTP_SEE_OTHER; } } $response = new OkResponse('', $status_code, $forward_url); if ($response->isRedirection()) { return $this->send($this->prepareRedirectResponse($forward_url, $status_code)); } return $this->respond($response); }
/** * Get the configuration of AMD * * @return array */ public function getConfig() { $defaults = array('baseUrl' => $this->baseUrl, 'paths' => $this->paths, 'shim' => $this->shim, 'deps' => $this->getDependencies(), 'waitSeconds' => 20); $params = array('defaults' => $defaults); return $this->hooks->trigger('config', 'amd', $params, $defaults); }