/** * Create an Elgg* object from a given entity row. * * Handles loading all tables into the correct class. * * @see get_entity_as_row() * @see add_subtype() * @see get_entity() * * @access private * * @param stdClass $row The row of the entry in the entities table. * @return ElggEntity|false * @throws ClassException * @throws InstallationException */ public function rowToElggStar($row) { if (!$row instanceof stdClass) { return $row; } if (!isset($row->guid) || !isset($row->subtype)) { return $row; } $class_name = $this->subtype_table->getClassFromId($row->subtype); if ($class_name && !class_exists($class_name)) { $this->logger->error("Class '{$class_name}' was not found, missing plugin?"); $class_name = ''; } if (!$class_name) { $map = ['object' => ElggObject::class, 'user' => ElggUser::class, 'group' => ElggGroup::class, 'site' => ElggSite::class]; if (isset($map[$row->type])) { $class_name = $map[$row->type]; } else { throw new InstallationException("Entity type {$row->type} is not supported."); } } $entity = new $class_name($row); if (!$entity instanceof ElggEntity) { throw new ClassException("{$class_name} must extend " . ElggEntity::class); } return $entity; }
/** * Run any php upgrade scripts which are required * * @param int $version Version upgrading from. * @param bool $quiet Suppress errors. Don't use this. * * @return bool */ protected function upgradeCode($version, $quiet = false) { $version = (int) $version; $upgrade_path = elgg_get_engine_path() . '/lib/upgrades/'; $processed_upgrades = $this->getProcessedUpgrades(); $upgrade_files = $this->getUpgradeFiles($upgrade_path); if ($upgrade_files === false) { return false; } $upgrades = $this->getUnprocessedUpgrades($upgrade_files, $processed_upgrades); // Sort and execute sort($upgrades); foreach ($upgrades as $upgrade) { $upgrade_version = $this->getUpgradeFileVersion($upgrade); $success = true; if ($upgrade_version <= $version) { // skip upgrade files from before the installation version of Elgg // because the upgrade files from before the installation version aren't // added to the database. continue; } // hide all errors. if ($quiet) { // hide include errors as well as any exceptions that might happen try { if (!@self::includeCode("{$upgrade_path}/{$upgrade}")) { $success = false; $this->logger->error("Could not include {$upgrade_path}/{$upgrade}"); } } catch (\Exception $e) { $success = false; $this->logger->error($e->getMessage()); } } else { if (!self::includeCode("{$upgrade_path}/{$upgrade}")) { $success = false; $this->logger->error("Could not include {$upgrade_path}/{$upgrade}"); } } if ($success) { // don't set the version to a lower number in instances where an upgrade // has been merged from a lower version of Elgg if ($upgrade_version > $version) { $this->datalist->set('version', $upgrade_version); } // incrementally set upgrade so we know where to start if something fails. $this->setProcessedUpgrade($upgrade); } else { return false; } } return true; }
/** * Verify a datalist name is valid * * @param string $name Datalist name to be checked * * @return bool */ protected function validateName($name) { // Can't use elgg_strlen() because not available until core loaded. if (is_callable('mb_strlen')) { $is_valid = mb_strlen($name) <= 255; } else { $is_valid = strlen($name) <= 255; } if (!$is_valid) { $this->logger->error("The name length for configuration variables cannot be greater than 255"); } return $is_valid; }
/** * Set the value for a datalist element. * * Plugin authors should use elgg_save_config() and pass null for the site GUID. * * @warning Names should be selected so as not to collide with the names for the * site config. * * @warning Values set here are not available in $CONFIG until next page load. * * @param string $name The name of the datalist * @param string $value The new value * * @return bool * @access private */ function set($name, $value) { $name = trim($name); // cannot store anything longer than 255 characters in db, so catch before we set if (elgg_strlen($name) > 255) { $this->logger->error("The name length for configuration variables cannot be greater than 255"); return false; } $escaped_name = $this->db->sanitizeString($name); $escaped_value = $this->db->sanitizeString($value); $success = $this->db->insertData("INSERT INTO {$this->table}" . " SET name = '{$escaped_name}', value = '{$escaped_value}'" . " ON DUPLICATE KEY UPDATE value = '{$escaped_value}'"); $this->cache->put($name, $value); return $success !== false; }
/** * Trigger all queries that were registered as "delayed" queries. This is * called by the system automatically on shutdown. * * @return void * @access private * @todo make protected once this class is part of public API */ public function executeDelayedQueries() { foreach ($this->delayedQueries as $set) { $query = $set[self::DELAYED_QUERY]; $type = $set[self::DELAYED_TYPE]; $handler = $set[self::DELAYED_HANDLER]; try { $stmt = $this->executeQuery($query, $this->getConnection($type)); if (is_callable($handler)) { call_user_func($handler, $stmt); } } catch (\Exception $e) { if ($this->logger) { // Suppress all exceptions since page already sent to requestor $this->logger->error($e); } } } }
/** * 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; }
/** * Add or update a config setting. * * Plugin authors should use elgg_set_config(). * * If the config name already exists, it will be updated to the new value. * * @note Internal: These settings are stored in the dbprefix_config table and read * during system boot into $CONFIG. * * @note Internal: The value is serialized so we maintain type information. * * @param string $name The name of the configuration value * @param mixed $value Its value * * @return bool */ function set($name, $value) { $name = trim($name); // cannot store anything longer than 255 characters in db, so catch before we set if (elgg_strlen($name) > 255) { $this->logger->error("The name length for configuration variables cannot be greater than 255"); return false; } $this->CONFIG->{$name} = $value; $dbprefix = $this->CONFIG->dbprefix; $sql = "\n\t\t\tINSERT INTO {$dbprefix}config\n\t\t\tSET name = :name,\n\t\t\t\tvalue = :value\n\t\t\tON DUPLICATE KEY UPDATE value = :value\n\t\t"; $params = [':name' => $name, ':value' => serialize($value)]; $version = (int) $this->CONFIG->version; if (!empty($version) && $version < 2016102500) { // need to do this the old way as long as site_guid columns have not been dropped $sql = "\n\t\t\t\tINSERT INTO {$dbprefix}config\n\t\t\t\tSET name = :name,\n\t\t\t\t\tvalue = :value,\n\t\t\t\t\tsite_guid = :site_guid\n\t\t\t\tON DUPLICATE KEY UPDATE value = :value\n\t\t\t"; $params[':site_guid'] = 1; } $result = $this->db->insertData($sql, $params); $this->boot->invalidateCache(); return $result !== false; }
/** * Validates class and returns an instance of batch * * @param string $class The fully qualified class name * @return boolean True if valid upgrade */ public function getBatch($class) { if (!class_exists($class)) { $this->logger->error("Upgrade class {$class} was not found"); return false; } $batch = new $class(); if (!$batch instanceof Batch) { $this->logger->error("Upgrade class {$class} should implement Elgg\\Upgrade\\Batch"); return false; } $version = $batch::VERSION; // Version must be in format yyyymmddnn if (preg_match("/^[0-9]{10}\$/", $version) == 0) { $this->logger->error("Upgrade {$class} defines an invalid upgrade version: {$version}"); return false; } if (!$batch->isRequired()) { return false; } return $batch; }