Файловый менеджер - Редактировать - /home/wuectly/www/03cbe/Collection.php.tar
Назад
home/wuectly/www/libraries/fof30/Update/Collection.php 0000604 00000023604 15245556140 0016743 0 ustar 00 <?php /** * @package FOF * @copyright Copyright (c)2010-2020 Nicholas K. Dionysopoulos / Akeeba Ltd * @license GNU General Public License version 2, or later */ namespace FOF30\Update; defined('_JEXEC') || die; use Exception; use FOF30\Container\Container; use FOF30\Download\Download; use SimpleXMLElement; class Collection { /** * Reads a "collection" XML update source and returns the complete tree of categories * and extensions applicable for platform version $jVersion * * @param string $url The collection XML update source URL to read from * @param string $jVersion Joomla! version to fetch updates for, or null to use JVERSION * * @return array A list of update sources applicable to $jVersion */ public function getAllUpdates($url, $jVersion = null) { // Get the target platform if (is_null($jVersion)) { $jVersion = JVERSION; } // Initialise return value $updates = [ 'metadata' => [ 'name' => '', 'description' => '', ], 'categories' => [], 'extensions' => [], ]; // Download and parse the XML file $container = Container::getInstance('com_foobar'); $downloader = new Download($container); $xmlSource = $downloader->getFromURL($url); try { $xml = new SimpleXMLElement($xmlSource, LIBXML_NONET); } catch (Exception $e) { return $updates; } // Sanity check if (($xml->getName() != 'extensionset')) { unset($xml); return $updates; } // Initialise return value with the stream metadata (name, description) $rootAttributes = $xml->attributes(); foreach ($rootAttributes as $k => $v) { $updates['metadata'][$k] = (string) $v; } // Initialise the raw list of updates $rawUpdates = [ 'categories' => [], 'extensions' => [], ]; // Segregate the raw list to a hierarchy of extension and category entries /** @var SimpleXMLElement $extension */ foreach ($xml->children() as $extension) { switch ($extension->getName()) { case 'category': // These are the parameters we expect in a category $params = [ 'name' => '', 'description' => '', 'category' => '', 'ref' => '', 'targetplatformversion' => $jVersion, ]; // These are the attributes of the element $attributes = $extension->attributes(); // Merge them all foreach ($attributes as $k => $v) { $params[$k] = (string) $v; } // We can't have a category with an empty category name if (empty($params['category'])) { continue; } // We can't have a category with an empty ref if (empty($params['ref'])) { continue; } if (empty($params['description'])) { $params['description'] = $params['category']; } if (!array_key_exists($params['category'], $rawUpdates['categories'])) { $rawUpdates['categories'][$params['category']] = []; } $rawUpdates['categories'][$params['category']][] = $params; break; case 'extension': // These are the parameters we expect in a category $params = [ 'element' => '', 'type' => '', 'version' => '', 'name' => '', 'detailsurl' => '', 'targetplatformversion' => $jVersion, ]; // These are the attributes of the element $attributes = $extension->attributes(); // Merge them all foreach ($attributes as $k => $v) { $params[$k] = (string) $v; } // We can't have an extension with an empty element if (empty($params['element'])) { continue; } // We can't have an extension with an empty type if (empty($params['type'])) { continue; } // We can't have an extension with an empty version if (empty($params['version'])) { continue; } if (empty($params['name'])) { $params['name'] = $params['element'] . ' ' . $params['version']; } if (!array_key_exists($params['type'], $rawUpdates['extensions'])) { $rawUpdates['extensions'][$params['type']] = []; } if (!array_key_exists($params['element'], $rawUpdates['extensions'][$params['type']])) { $rawUpdates['extensions'][$params['type']][$params['element']] = []; } $rawUpdates['extensions'][$params['type']][$params['element']][] = $params; break; default: break; } } unset($xml); if (!empty($rawUpdates['categories'])) { foreach ($rawUpdates['categories'] as $category => $entries) { $update = $this->filterListByPlatform($entries, $jVersion); $updates['categories'][$category] = $update; } } if (!empty($rawUpdates['extensions'])) { foreach ($rawUpdates['extensions'] as $type => $extensions) { $updates['extensions'][$type] = []; if (!empty($extensions)) { foreach ($extensions as $element => $entries) { $update = $this->filterListByPlatform($entries, $jVersion); $updates['extensions'][$type][$element] = $update; } } } } return $updates; } /** * Returns only the category definitions of a collection * * @param string $url The URL of the collection update source * @param string $jVersion Joomla! version to fetch updates for, or null to use JVERSION * * @return array An array of category update definitions */ public function getCategories($url, $jVersion = null) { $allUpdates = $this->getAllUpdates($url, $jVersion); return $allUpdates['categories']; } /** * Returns the update source for a specific category * * @param string $url The URL of the collection update source * @param string $category The category name you want to get the update source URL of * @param string $jVersion Joomla! version to fetch updates for, or null to use JVERSION * * @return string|null The update stream URL, or null if it's not found */ public function getCategoryUpdateSource($url, $category, $jVersion = null) { $allUpdates = $this->getAllUpdates($url, $jVersion); if (array_key_exists($category, $allUpdates['categories'])) { return $allUpdates['categories'][$category]['ref']; } else { return null; } } /** * Get a list of updates for extensions only, optionally of a specific type * * @param string $url The URL of the collection update source * @param string $type The extension type you want to get the update source URL of, empty to get all * extension types * @param string $jVersion Joomla! version to fetch updates for, or null to use JVERSION * * @return array|null An array of extension update definitions or null if none is found */ public function getExtensions($url, $type = null, $jVersion = null) { $allUpdates = $this->getAllUpdates($url, $jVersion); if (empty($type)) { return $allUpdates['extensions']; } elseif (array_key_exists($type, $allUpdates['extensions'])) { return $allUpdates['extensions'][$type]; } else { return null; } } /** * Get the update source URL for a specific extension, based on the type and element, e.g. * type=file and element=joomla is Joomla! itself. * * @param string $url The URL of the collection update source * @param string $type The extension type you want to get the update source URL of * @param string $element The extension element you want to get the update source URL of * @param string $jVersion Joomla! version to fetch updates for, or null to use JVERSION * * @return string|null The update source URL or null if the extension is not found */ public function getExtensionUpdateSource($url, $type, $element, $jVersion = null) { $allUpdates = $this->getExtensions($url, $type, $jVersion); if (empty($allUpdates)) { return null; } elseif (array_key_exists($element, $allUpdates)) { return $allUpdates[$element]['detailsurl']; } else { return null; } } /** * Filters a list of updates, returning only those available for the * specified platform version $jVersion * * @param array $updates An array containing update definitions (categories or extensions) * @param string $jVersion Joomla! version to fetch updates for, or null to use JVERSION * * @return array|null The update definition that is compatible, or null if none is compatible */ private function filterListByPlatform($updates, $jVersion = null) { // Get the target platform if (is_null($jVersion)) { $jVersion = JVERSION; } $versionParts = explode('.', $jVersion, 4); $platformVersionMajor = $versionParts[0]; $platformVersionMinor = (count($versionParts) > 1) ? $platformVersionMajor . '.' . $versionParts[1] : $platformVersionMajor; $platformVersionNormal = (count($versionParts) > 2) ? $platformVersionMinor . '.' . $versionParts[2] : $platformVersionMinor; $platformVersionFull = (count($versionParts) > 3) ? $platformVersionNormal . '.' . $versionParts[3] : $platformVersionNormal; $pickedExtension = null; $pickedSpecificity = -1; foreach ($updates as $update) { // Test the target platform $targetPlatform = (string) $update['targetplatformversion']; if ($targetPlatform === $platformVersionFull) { $pickedExtension = $update; $pickedSpecificity = 4; } elseif (($targetPlatform === $platformVersionNormal) && ($pickedSpecificity <= 3)) { $pickedExtension = $update; $pickedSpecificity = 3; } elseif (($targetPlatform === $platformVersionMinor) && ($pickedSpecificity <= 2)) { $pickedExtension = $update; $pickedSpecificity = 2; } elseif (($targetPlatform === $platformVersionMajor) && ($pickedSpecificity <= 1)) { $pickedExtension = $update; $pickedSpecificity = 1; } } return $pickedExtension; } } home/wuectly/www/libraries/fof40/Utils/Collection.php 0000604 00000035075 15245567002 0016626 0 ustar 00 <?php /** * @package FOF * @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd * @license GNU General Public License version 3, or later */ namespace FOF40\Utils; defined('_JEXEC') || die; use ArrayAccess; use ArrayIterator; use CachingIterator; use Closure; use Countable; use IteratorAggregate; use JsonSerializable; class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable { /** * The items contained in the collection. * * @var array */ protected $items = []; /** * Create a new collection. * * @param array $items */ public function __construct(array $items = []) { $this->items = $items; } /** * Create a new collection instance if the value isn't one already. If given an array then the array is wrapped in * a Collection. Otherwise we return a Collection with only one item, whatever was passed in $items. If you pass * null you get an empty Collection. * * @param array|mixed $items * * @return static */ public static function make($items): Collection { if (is_null($items)) { return new static; } if ($items instanceof Collection) { return $items; } return new static(is_array($items) ? $items : [$items]); } /** * Get all of the items in the collection. * * @return array */ public function all(): array { return $this->items; } /** * Collapse the collection items into a single array. This assumes that the Collection is composed of arrays. We * are essentially merging all of these arrays and creating a new Collection out of them. * * If $this->items = [ ['a','b'], ['c','d'], ['e'] ] after collapse it becomes [ 'a','b','c','d','e' ] * * @return Collection */ public function collapse(): Collection { $results = []; foreach ($this->items as $values) { $results = array_merge($results, $values); } return new static($results); } /** * Diff the collection with the given items. * * @param Collection|array $items * * @return Collection */ public function diff($items): Collection { return new static(array_diff($this->items, $this->getIterableItemsAsArray($items))); } /** * Execute a callback over each item. * * @param Closure $callback * * @return Collection */ public function each(Closure $callback): Collection { array_map($callback, $this->items); return $this; } /** * Fetch a nested element of the collection. * * @param string $key * * @return Collection */ public function fetch(string $key): Collection { return new static(array_fetch($this->items, $key)); } /** * Run a filter over each of the items. * * @param Closure $callback * * @return Collection */ public function filter(Closure $callback): Collection { return new static(array_filter($this->items, $callback)); } /** * Get the first item from the collection. * * @param \Closure $callback * @param mixed $default * * @return mixed|null */ public function first(Closure $callback = null, $default = null) { if (is_null($callback)) { return count($this->items) > 0 ? reset($this->items) : null; } else { return array_first($this->items, $callback, $default); } } /** * Get a flattened array of the items in the collection. * * @return Collection */ public function flatten(): Collection { return new static(array_flatten($this->items)); } /** * Remove an item from the collection by key. * * @param mixed $key * * @return void */ public function forget(string $key): void { unset($this->items[$key]); } /** * Get an item from the collection by key. * * @param mixed $key * @param mixed $default * * @return mixed */ public function get(string $key, $default = null) { if (array_key_exists($key, $this->items)) { return $this->items[$key]; } return value($default); } /** * Group an associative array by a field or Closure value. * * @param callable|string $groupBy * * @return Collection */ public function groupBy($groupBy): Collection { $results = []; foreach ($this->items as $key => $value) { $key = is_callable($groupBy) ? $groupBy($value, $key) : array_get($value, $groupBy); $results[$key][] = $value; } return new static($results); } /** * Determine if an item exists in the collection by key. * * @param string $key * * @return bool */ public function has(string $key): bool { return array_key_exists($key, $this->items); } /** * Concatenate values of a given key as a string. * * @param string $value * @param string|null $glue * * @return string */ public function implode(string $value, ?string $glue = null): string { if (is_null($glue)) { return implode($this->lists($value)); } return implode($glue, $this->lists($value)); } /** * Intersect the collection with the given items. * * @param Collection|array $items * * @return Collection */ public function intersect($items): Collection { return new static(array_intersect($this->items, $this->getIterableItemsAsArray($items))); } /** * Determine if the collection is empty or not. * * @return bool */ public function isEmpty(): bool { return empty($this->items); } /** * Get the last item from the collection. * * @return mixed|null */ public function last() { return count($this->items) > 0 ? end($this->items) : null; } /** * Get an array with the values of a given key. * * @param string $value * @param string|null $key * * @return array */ public function lists(string $value, ?string $key = null) { return array_pluck($this->items, $value, $key); } /** * Run a map over each of the items. * * @param Closure $callback * * @return Collection */ public function map(Closure $callback): Collection { return new static(array_map($callback, $this->items, array_keys($this->items))); } /** * Merge the collection with the given items. * * @param Collection|array $items * * @return Collection */ public function merge($items): Collection { return new static(array_merge($this->items, $this->getIterableItemsAsArray($items))); } /** * Get and remove the last item from the collection. * * @return mixed|null */ public function pop() { return array_pop($this->items); } /** * Push an item onto the beginning of the collection. * * @param mixed $value * * @return void */ public function prepend($value): void { array_unshift($this->items, $value); } /** * Push an item onto the end of the collection. * * @param mixed $value * * @return void */ public function push($value): void { $this->items[] = $value; } /** * Put an item in the collection by key. * * @param string $key * @param mixed $value * * @return void */ public function put(string $key, $value): void { $this->items[$key] = $value; } /** * Reduce the collection to a single value. * * @param callable $callback * @param mixed $initial * * @return mixed */ public function reduce(callable $callback, $initial = null) { return array_reduce($this->items, $callback, $initial); } /** * Get one or more items randomly from the collection. * * @param int $amount * * @return mixed */ public function random(int $amount = 1) { $keys = array_rand($this->items, $amount); return is_array($keys) ? array_intersect_key($this->items, array_flip($keys)) : $this->items[$keys]; } /** * Reverse items order. * * @return Collection */ public function reverse(): Collection { return new static(array_reverse($this->items)); } /** * Get and remove the first item from the collection. * * @return mixed|null */ public function shift() { return array_shift($this->items); } /** * Slice the underlying collection array. * * @param int $offset * @param int|null $length * @param bool $preserveKeys * * @return Collection */ public function slice(int $offset, ?int $length = null, bool $preserveKeys = false): Collection { return new static(array_slice($this->items, $offset, $length, $preserveKeys)); } /** * Sort through each item with a callback. * * @param Closure $callback * * @return Collection */ public function sort(Closure $callback): Collection { uasort($this->items, $callback); return $this; } /** * Sort the collection using the given Closure. * * @param \Closure|string $callback * @param int $options * @param bool $descending * * @return Collection */ public function sortBy($callback, int $options = SORT_REGULAR, bool $descending = false): Collection { $results = []; if (is_string($callback)) { $callback = $this->valueRetriever($callback); } // First we will loop through the items and get the comparator from a callback // function which we were given. Then, we will sort the returned values and // and grab the corresponding values for the sorted keys from this array. foreach ($this->items as $key => $value) { $results[$key] = $callback($value); } $descending ? arsort($results, $options) : asort($results, $options); // Once we have sorted all of the keys in the array, we will loop through them // and grab the corresponding model so we can set the underlying items list // to the sorted version. Then we'll just return the collection instance. foreach (array_keys($results) as $key) { $results[$key] = $this->items[$key]; } $this->items = $results; return $this; } /** * Sort the collection in descending order using the given Closure. * * @param \Closure|string $callback * @param int $options * * @return Collection */ public function sortByDesc($callback, int $options = SORT_REGULAR): Collection { return $this->sortBy($callback, $options, true); } /** * Splice portion of the underlying collection array. * * @param int $offset * @param int $length * @param mixed $replacement * * @return Collection */ public function splice(int $offset, int $length = 0, $replacement = []): Collection { return new static(array_splice($this->items, $offset, $length, $replacement)); } /** * Get the sum of the given values. * * @param \Closure|string $callback * * @return mixed */ public function sum($callback) { if (is_string($callback)) { $callback = $this->valueRetriever($callback); } return $this->reduce(function ($result, $item) use ($callback) { return $result += $callback($item); }, 0); } /** * Take the first or last {$limit} items. * * @param int|null $limit * * @return Collection */ public function take(?int $limit = null): Collection { if ($limit < 0) { return $this->slice($limit, abs($limit)); } return $this->slice(0, $limit); } /** * Resets the Collection (removes all items) * * @return Collection */ public function reset(): Collection { $this->items = []; return $this; } /** * Transform each item in the collection using a callback. * * @param callable $callback * * @return Collection */ public function transform(callable $callback): Collection { $this->items = array_map($callback, $this->items); return $this; } /** * Return only unique items from the collection array. * * @return Collection */ public function unique(): Collection { return new static(array_unique($this->items)); } /** * Reset the keys on the underlying array. * * @return Collection */ public function values(): Collection { $this->items = array_values($this->items); return $this; } /** * Get the collection of items as a plain array. * * @return array */ public function toArray(): array { return array_map(function ($value) { return (is_object($value) && method_exists($value, 'toArray')) ? $value->toArray() : $value; }, $this->items); } /** * Convert the object into something JSON serializable. * * @return array */ #[\ReturnTypeWillChange] public function jsonSerialize(): array { return $this->toArray(); } /** * Get the collection of items as JSON. * * @param int $options * * @return string */ public function toJson(int $options = 0): string { return json_encode($this->toArray(), $options); } /** * Get an iterator for the items. * * @return ArrayIterator */ public function getIterator(): ArrayIterator { return new ArrayIterator($this->items); } /** * Get a CachingIterator instance. * * @param integer $flags Caching iterator flags * * @return \CachingIterator */ public function getCachingIterator(int $flags = CachingIterator::CALL_TOSTRING): CachingIterator { return new \CachingIterator($this->getIterator(), $flags); } /** * Count the number of items in the collection. * * @return int */ public function count(): int { return count($this->items); } /** * Determine if an item exists at an offset. * * @param mixed $key * * @return bool */ public function offsetExists($key): bool { return array_key_exists($key, $this->items); } /** * Get an item at a given offset. * * @param mixed $key * * @return mixed */ #[\ReturnTypeWillChange] public function offsetGet($key) { return $this->items[$key]; } /** * Set the item at a given offset. * * @param mixed $key * @param mixed $value * * @return void */ #[\ReturnTypeWillChange] public function offsetSet($key, $value) { if (is_null($key)) { $this->items[] = $value; } else { $this->items[$key] = $value; } } /** * Unset the item at a given offset. * * @param string $key * * @return void */ #[\ReturnTypeWillChange] public function offsetUnset($key) { unset($this->items[$key]); } /** * Convert the collection to its string representation. * * @return string */ public function __toString(): string { return $this->toJson(); } /** * Get a value retrieving callback. * * @param string $value * * @return \Closure */ protected function valueRetriever(string $value): callable { return function ($item) use ($value) { return is_object($item) ? $item->{$value} : array_get($item, $value); }; } /** * Results array of items from Collection. * * @param Collection|array $items * * @return array */ private function getIterableItemsAsArray($items): array { if ($items instanceof Collection) { $items = $items->all(); } elseif (is_object($items) && method_exists($items, 'toArray')) { $items = $items->toArray(); } return $items; } } home/wuectly/www/libraries/fof30/Model/DataModel/Collection.php 0000604 00000015352 15245567747 0020433 0 ustar 00 <?php /** * @package FOF * @copyright Copyright (c)2010-2020 Nicholas K. Dionysopoulos / Akeeba Ltd * @license GNU General Public License version 2, or later */ namespace FOF30\Model\DataModel; defined('_JEXEC') || die; use FOF30\Model\DataModel; use FOF30\Utils\Collection as BaseCollection; /** * A collection of data models. You can enumerate it like an array, use it everywhere a collection is expected (e.g. a * foreach loop) and even implements a countable interface. You can also batch-apply DataModel methods on it thanks to * its magic __call() method, hence the type-hinting below. * * @method void setFieldValue(string $name, mixed $value = '') * @method void archive() * @method void save(mixed $data, string $orderingFilter = '', bool $ignore = null) * @method void push(mixed $data, string $orderingFilter = '', bool $ignore = null, array $relations = null) * @method void bind(mixed $data, array $ignore = []) * @method void check() * @method void reorder(string $where = '') * @method void delete(mixed $id = null) * @method void trash(mixed $id) * @method void forceDelete(mixed $id = null) * @method void lock(int $userId = null) * @method void move(int $delta, string $where = '') * @method void publish() * @method void restore(mixed $id) * @method void touch(int $userId = null) * @method void unlock() * @method void unpublish() */ class Collection extends BaseCollection { /** * Find a model in the collection by key. * * @param mixed $key * @param mixed $default * * @return DataModel */ public function find($key, $default = null) { if ($key instanceof DataModel) { $key = $key->getId(); } return array_first($this->items, function ($itemKey, $model) use ($key) { /** @var DataModel $model */ return $model->getId() == $key; }, $default); } /** * Remove an item in the collection by key * * @param mixed $key * * @return void */ public function removeById($key) { if ($key instanceof DataModel) { $key = $key->getId(); } $index = array_search($key, $this->modelKeys()); if ($index !== false) { unset($this->items[$index]); } } /** * Add an item to the collection. * * @param mixed $item * * @return Collection */ public function add($item) { $this->items[] = $item; return $this; } /** * Determine if a key exists in the collection. * * @param mixed $key * * @return bool */ public function contains($key) { return !is_null($this->find($key)); } /** * Fetch a nested element of the collection. * * @param string $key * * @return Collection */ public function fetch($key) { return new static(array_fetch($this->toArray(), $key)); } /** * Get the max value of a given key. * * @param string $key * * @return mixed */ public function max($key) { return $this->reduce(function ($result, $item) use ($key) { return (is_null($result) || $item->{$key} > $result) ? $item->{$key} : $result; }); } /** * Get the min value of a given key. * * @param string $key * * @return mixed */ public function min($key) { return $this->reduce(function ($result, $item) use ($key) { return (is_null($result) || $item->{$key} < $result) ? $item->{$key} : $result; }); } /** * Get the array of primary keys * * @return array */ public function modelKeys() { return array_map( function ($m) { /** @var DataModel $m */ return $m->getId(); }, $this->items); } /** * Merge the collection with the given items. * * @param BaseCollection|array $collection * * @return BaseCollection */ public function merge($collection) { $dictionary = $this->getDictionary($this); foreach ($collection as $item) { $dictionary[$item->getId()] = $item; } return new static(array_values($dictionary)); } /** * Diff the collection with the given items. * * @param BaseCollection|array $collection * * @return BaseCollection */ public function diff($collection) { $diff = new static; $dictionary = $this->getDictionary($collection); foreach ($this->items as $item) { /** @var DataModel $item */ if (!isset($dictionary[$item->getId()])) { $diff->add($item); } } return $diff; } /** * Intersect the collection with the given items. * * @param BaseCollection|array $collection * * @return Collection */ public function intersect($collection) { $intersect = new static; $dictionary = $this->getDictionary($collection); foreach ($this->items as $item) { /** @var DataModel $item */ if (isset($dictionary[$item->getId()])) { $intersect->add($item); } } return $intersect; } /** * Return only unique items from the collection. * * @return BaseCollection */ public function unique() { $dictionary = $this->getDictionary($this); return new static(array_values($dictionary)); } /** * Get a base Support collection instance from this collection. * * @return BaseCollection */ public function toBase() { return new BaseCollection($this->items); } /** * Magic method which allows you to run a DataModel method to all items in the collection. * * For example, you can do $collection->save('foobar' => 1) to update the 'foobar' column to 1 across all items in * the collection. * * IMPORTANT: The return value of the method call is not returned back to you! * * @param string $name The method to call * @param array $arguments The arguments to the method */ public function __call($name, $arguments) { if (!count($this)) { return; } $class = get_class($this->first()); if (method_exists($class, $name)) { foreach ($this as $item) { switch (count($arguments)) { case 0: $item->$name(); break; case 1: $item->$name($arguments[0]); break; case 2: $item->$name($arguments[0], $arguments[1]); break; case 3: $item->$name($arguments[0], $arguments[1], $arguments[2]); break; case 4: $item->$name($arguments[0], $arguments[1], $arguments[2], $arguments[3]); break; case 5: $item->$name($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4]); break; case 6: $item->$name($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5]); break; default: call_user_func_array([$item, $name], $arguments); break; } } } } /** * Get a dictionary keyed by primary keys. * * @param BaseCollection $collection * * @return array */ protected function getDictionary($collection) { $dictionary = []; foreach ($collection as $value) { $dictionary[$value->getId()] = $value; } return $dictionary; } } home/wuectly/www/libraries/fof40/Update/Collection.php 0000604 00000023727 15245570523 0016753 0 ustar 00 <?php /** * @package FOF * @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd * @license GNU General Public License version 3, or later */ namespace FOF40\Update; defined('_JEXEC') || die; use Exception; use FOF40\Container\Container; use FOF40\Download\Download; use SimpleXMLElement; class Collection { /** * Reads a "collection" XML update source and returns the complete tree of categories * and extensions applicable for platform version $jVersion * * @param string $url The collection XML update source URL to read from * @param string|null $jVersion Joomla! version to fetch updates for, or null to use JVERSION * * @return array A list of update sources applicable to $jVersion */ public function getAllUpdates(string $url, ?string $jVersion = null): array { // Get the target platform if (is_null($jVersion)) { $jVersion = JVERSION; } // Initialise return value $updates = [ 'metadata' => [ 'name' => '', 'description' => '', ], 'categories' => [], 'extensions' => [], ]; // Download and parse the XML file $container = Container::getInstance('com_foobar'); $downloader = new Download($container); $xmlSource = $downloader->getFromURL($url); try { $xml = new SimpleXMLElement($xmlSource, LIBXML_NONET); } catch (Exception $e) { return $updates; } // Sanity check if (($xml->getName() != 'extensionset')) { unset($xml); return $updates; } // Initialise return value with the stream metadata (name, description) $rootAttributes = $xml->attributes(); foreach ($rootAttributes as $k => $v) { $updates['metadata'][$k] = (string) $v; } // Initialise the raw list of updates $rawUpdates = [ 'categories' => [], 'extensions' => [], ]; // Segregate the raw list to a hierarchy of extension and category entries /** @var SimpleXMLElement $extension */ foreach ($xml->children() as $extension) { switch ($extension->getName()) { case 'category': // These are the parameters we expect in a category $params = [ 'name' => '', 'description' => '', 'category' => '', 'ref' => '', 'targetplatformversion' => $jVersion, ]; // These are the attributes of the element $attributes = $extension->attributes(); // Merge them all foreach ($attributes as $k => $v) { $params[$k] = (string) $v; } // We can't have a category with an empty category name if (empty($params['category'])) { continue; } // We can't have a category with an empty ref if (empty($params['ref'])) { continue; } if (empty($params['description'])) { $params['description'] = $params['category']; } if (!array_key_exists($params['category'], $rawUpdates['categories'])) { $rawUpdates['categories'][$params['category']] = []; } $rawUpdates['categories'][$params['category']][] = $params; break; case 'extension': // These are the parameters we expect in a category $params = [ 'element' => '', 'type' => '', 'version' => '', 'name' => '', 'detailsurl' => '', 'targetplatformversion' => $jVersion, ]; // These are the attributes of the element $attributes = $extension->attributes(); // Merge them all foreach ($attributes as $k => $v) { $params[$k] = (string) $v; } // We can't have an extension with an empty element if (empty($params['element'])) { continue; } // We can't have an extension with an empty type if (empty($params['type'])) { continue; } // We can't have an extension with an empty version if (empty($params['version'])) { continue; } if (empty($params['name'])) { $params['name'] = $params['element'] . ' ' . $params['version']; } if (!array_key_exists($params['type'], $rawUpdates['extensions'])) { $rawUpdates['extensions'][$params['type']] = []; } if (!array_key_exists($params['element'], $rawUpdates['extensions'][$params['type']])) { $rawUpdates['extensions'][$params['type']][$params['element']] = []; } $rawUpdates['extensions'][$params['type']][$params['element']][] = $params; break; default: break; } } unset($xml); foreach ($rawUpdates['categories'] as $category => $entries) { $update = $this->filterListByPlatform($entries, $jVersion); $updates['categories'][$category] = $update; } foreach ($rawUpdates['extensions'] as $type => $extensions) { $updates['extensions'][$type] = []; foreach ($extensions as $element => $entries) { $update = $this->filterListByPlatform($entries, $jVersion); $updates['extensions'][$type][$element] = $update; } } return $updates; } /** * Returns only the category definitions of a collection * * @param string $url The URL of the collection update source * @param string|null $jVersion Joomla! version to fetch updates for, or null to use JVERSION * * @return array An array of category update definitions */ public function getCategories(string $url, ?string $jVersion = null): array { $allUpdates = $this->getAllUpdates($url, $jVersion); return $allUpdates['categories']; } /** * Returns the update source for a specific category * * @param string $url The URL of the collection update source * @param string $category The category name you want to get the update source URL of * @param string|null $jVersion Joomla! version to fetch updates for, or null to use JVERSION * * @return string|null The update stream URL, or null if it's not found */ public function getCategoryUpdateSource(string $url, string $category, ?string $jVersion = null): ?string { $allUpdates = $this->getAllUpdates($url, $jVersion); if (array_key_exists($category, $allUpdates['categories'])) { return $allUpdates['categories'][$category]['ref']; } else { return null; } } /** * Get a list of updates for extensions only, optionally of a specific type * * @param string $url The URL of the collection update source * @param string $type The extension type you want to get the update source URL of, empty to get all * extension types * @param string|null $jVersion Joomla! version to fetch updates for, or null to use JVERSION * * @return array|null An array of extension update definitions or null if none is found */ public function getExtensions(string $url, ?string $type = null, ?string $jVersion = null): ?array { $allUpdates = $this->getAllUpdates($url, $jVersion); if (empty($type)) { return $allUpdates['extensions']; } elseif (array_key_exists($type, $allUpdates['extensions'])) { return $allUpdates['extensions'][$type]; } else { return null; } } /** * Get the update source URL for a specific extension, based on the type and element, e.g. * type=file and element=joomla is Joomla! itself. * * @param string $url The URL of the collection update source * @param string $type The extension type you want to get the update source URL of * @param string $element The extension element you want to get the update source URL of * @param string|null $jVersion Joomla! version to fetch updates for, or null to use JVERSION * * @return string|null The update source URL or null if the extension is not found */ public function getExtensionUpdateSource(string $url, string $type, string $element, ?string $jVersion = null): ?string { $allUpdates = $this->getExtensions($url, $type, $jVersion); if (empty($allUpdates)) { return null; } elseif (array_key_exists($element, $allUpdates)) { return $allUpdates[$element]['detailsurl']; } else { return null; } } /** * Filters a list of updates, returning only those available for the * specified platform version $jVersion * * @param array $updates An array containing update definitions (categories or extensions) * @param string $jVersion Joomla! version to fetch updates for, or null to use JVERSION * * @return array|null The update definition that is compatible, or null if none is compatible */ private function filterListByPlatform(array $updates, ?string $jVersion = null): ?array { // Get the target platform if (is_null($jVersion)) { $jVersion = JVERSION; } $versionParts = explode('.', $jVersion, 4); $platformVersionMajor = $versionParts[0]; $platformVersionMinor = (count($versionParts) > 1) ? $platformVersionMajor . '.' . $versionParts[1] : $platformVersionMajor; $platformVersionNormal = (count($versionParts) > 2) ? $platformVersionMinor . '.' . $versionParts[2] : $platformVersionMinor; $platformVersionFull = (count($versionParts) > 3) ? $platformVersionNormal . '.' . $versionParts[3] : $platformVersionNormal; $pickedExtension = null; $pickedSpecificity = -1; foreach ($updates as $update) { // Test the target platform $targetPlatform = (string) $update['targetplatformversion']; if ($targetPlatform === $platformVersionFull) { $pickedExtension = $update; $pickedSpecificity = 4; } elseif (($targetPlatform === $platformVersionNormal) && ($pickedSpecificity <= 3)) { $pickedExtension = $update; $pickedSpecificity = 3; } elseif (($targetPlatform === $platformVersionMinor) && ($pickedSpecificity <= 2)) { $pickedExtension = $update; $pickedSpecificity = 2; } elseif (($targetPlatform === $platformVersionMajor) && ($pickedSpecificity <= 1)) { $pickedExtension = $update; $pickedSpecificity = 1; } } return $pickedExtension; } } home/wuectly/www/libraries/fof30/Utils/Collection.php 0000604 00000032507 15245572020 0016616 0 ustar 00 <?php /** * @package FOF * @copyright Copyright (c)2010-2020 Nicholas K. Dionysopoulos / Akeeba Ltd * @license GNU General Public License version 2, or later */ namespace FOF30\Utils; defined('_JEXEC') || die; use ArrayAccess; use ArrayIterator; use CachingIterator; use Closure; use Countable; use IteratorAggregate; use JsonSerializable; class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable { /** * The items contained in the collection. * * @var array */ protected $items = []; /** * Create a new collection. * * @param array $items */ public function __construct(array $items = []) { $this->items = $items; } /** * Create a new collection instance if the value isn't one already. * * @param mixed $items * * @return static */ public static function make($items) { if (is_null($items)) { return new static; } if ($items instanceof Collection) { return $items; } return new static(is_array($items) ? $items : [$items]); } /** * Get all of the items in the collection. * * @return array */ public function all() { return $this->items; } /** * Collapse the collection items into a single array. * * @return static */ public function collapse() { $results = []; foreach ($this->items as $values) { $results = array_merge($results, $values); } return new static($results); } /** * Diff the collection with the given items. * * @param Collection|array $items * * @return static */ public function diff($items) { return new static(array_diff($this->items, $this->getArrayableItems($items))); } /** * Execute a callback over each item. * * @param Closure $callback * * @return static */ public function each(Closure $callback) { array_map($callback, $this->items); return $this; } /** * Fetch a nested element of the collection. * * @param string $key * * @return static */ public function fetch($key) { return new static(array_fetch($this->items, $key)); } /** * Run a filter over each of the items. * * @param Closure $callback * * @return static */ public function filter(Closure $callback) { return new static(array_filter($this->items, $callback)); } /** * Get the first item from the collection. * * @param Closure $callback * @param mixed $default * * @return mixed|null */ public function first(Closure $callback = null, $default = null) { if (is_null($callback)) { return count($this->items) > 0 ? reset($this->items) : null; } else { return array_first($this->items, $callback, $default); } } /** * Get a flattened array of the items in the collection. * * @return array */ public function flatten() { return new static(array_flatten($this->items)); } /** * Remove an item from the collection by key. * * @param mixed $key * * @return void */ public function forget($key) { unset($this->items[$key]); } /** * Get an item from the collection by key. * * @param mixed $key * @param mixed $default * * @return mixed */ public function get($key, $default = null) { if (array_key_exists($key, $this->items)) { return $this->items[$key]; } return value($default); } /** * Group an associative array by a field or Closure value. * * @param callable|string $groupBy * * @return static */ public function groupBy($groupBy) { $results = []; foreach ($this->items as $key => $value) { $key = is_callable($groupBy) ? $groupBy($value, $key) : array_get($value, $groupBy); $results[$key][] = $value; } return new static($results); } /** * Determine if an item exists in the collection by key. * * @param mixed $key * * @return bool */ public function has($key) { return array_key_exists($key, $this->items); } /** * Concatenate values of a given key as a string. * * @param string $value * @param string $glue * * @return string */ public function implode($value, $glue = null) { if (is_null($glue)) { return implode($this->lists($value)); } return implode($glue, $this->lists($value)); } /** * Intersect the collection with the given items. * * @param Collection|array $items * * @return static */ public function intersect($items) { return new static(array_intersect($this->items, $this->getArrayableItems($items))); } /** * Determine if the collection is empty or not. * * @return bool */ public function isEmpty() { return empty($this->items); } /** * Get the last item from the collection. * * @return mixed|null */ public function last() { return count($this->items) > 0 ? end($this->items) : null; } /** * Get an array with the values of a given key. * * @param string $value * @param string $key * * @return array */ public function lists($value, $key = null) { return array_pluck($this->items, $value, $key); } /** * Run a map over each of the items. * * @param Closure $callback * * @return static */ public function map(Closure $callback) { return new static(array_map($callback, $this->items, array_keys($this->items))); } /** * Merge the collection with the given items. * * @param Collection|array $items * * @return static */ public function merge($items) { return new static(array_merge($this->items, $this->getArrayableItems($items))); } /** * Get and remove the last item from the collection. * * @return mixed|null */ public function pop() { return array_pop($this->items); } /** * Push an item onto the beginning of the collection. * * @param mixed $value * * @return void */ public function prepend($value) { array_unshift($this->items, $value); } /** * Push an item onto the end of the collection. * * @param mixed $value * * @return void */ public function push($value) { $this->items[] = $value; } /** * Put an item in the collection by key. * * @param mixed $key * @param mixed $value * * @return void */ public function put($key, $value) { $this->items[$key] = $value; } /** * Reduce the collection to a single value. * * @param callable $callback * @param mixed $initial * * @return mixed */ public function reduce($callback, $initial = null) { return array_reduce($this->items, $callback, $initial); } /** * Get one or more items randomly from the collection. * * @param int $amount * * @return mixed */ public function random($amount = 1) { $keys = array_rand($this->items, $amount); return is_array($keys) ? array_intersect_key($this->items, array_flip($keys)) : $this->items[$keys]; } /** * Reverse items order. * * @return static */ public function reverse() { return new static(array_reverse($this->items)); } /** * Get and remove the first item from the collection. * * @return mixed|null */ public function shift() { return array_shift($this->items); } /** * Slice the underlying collection array. * * @param int $offset * @param int $length * @param bool $preserveKeys * * @return static */ public function slice($offset, $length = null, $preserveKeys = false) { return new static(array_slice($this->items, $offset, $length, $preserveKeys)); } /** * Sort through each item with a callback. * * @param Closure $callback * * @return static */ public function sort(Closure $callback) { uasort($this->items, $callback); return $this; } /** * Sort the collection using the given Closure. * * @param Closure|string $callback * @param int $options * @param bool $descending * * @return static */ public function sortBy($callback, $options = SORT_REGULAR, $descending = false) { $results = []; if (is_string($callback)) { $callback = $this->valueRetriever($callback); } // First we will loop through the items and get the comparator from a callback // function which we were given. Then, we will sort the returned values and // and grab the corresponding values for the sorted keys from this array. foreach ($this->items as $key => $value) { $results[$key] = $callback($value); } $descending ? arsort($results, $options) : asort($results, $options); // Once we have sorted all of the keys in the array, we will loop through them // and grab the corresponding model so we can set the underlying items list // to the sorted version. Then we'll just return the collection instance. foreach (array_keys($results) as $key) { $results[$key] = $this->items[$key]; } $this->items = $results; return $this; } /** * Sort the collection in descending order using the given Closure. * * @param Closure|string $callback * @param int $options * * @return static */ public function sortByDesc($callback, $options = SORT_REGULAR) { return $this->sortBy($callback, $options, true); } /** * Splice portion of the underlying collection array. * * @param int $offset * @param int $length * @param mixed $replacement * * @return static */ public function splice($offset, $length = 0, $replacement = []) { return new static(array_splice($this->items, $offset, $length, $replacement)); } /** * Get the sum of the given values. * * @param Closure|string $callback * * @return mixed */ public function sum($callback) { if (is_string($callback)) { $callback = $this->valueRetriever($callback); } return $this->reduce(function ($result, $item) use ($callback) { return $result += $callback($item); }, 0); } /** * Take the first or last {$limit} items. * * @param int $limit * * @return static */ public function take($limit = null) { if ($limit < 0) { return $this->slice($limit, abs($limit)); } return $this->slice(0, $limit); } /** * Resets the Collection (removes all items) * * @return Collection */ public function reset() { $this->items = []; return $this; } /** * Transform each item in the collection using a callback. * * @param callable $callback * * @return static */ public function transform($callback) { $this->items = array_map($callback, $this->items); return $this; } /** * Return only unique items from the collection array. * * @return static */ public function unique() { return new static(array_unique($this->items)); } /** * Reset the keys on the underlying array. * * @return static */ public function values() { $this->items = array_values($this->items); return $this; } /** * Get the collection of items as a plain array. * * @return array */ public function toArray() { return array_map(function ($value) { return (is_object($value) && method_exists($value, 'toArray')) ? $value->toArray() : $value; }, $this->items); } /** * Convert the object into something JSON serializable. * * @return array */ public function jsonSerialize() { return $this->toArray(); } /** * Get the collection of items as JSON. * * @param int $options * * @return string */ public function toJson($options = 0) { return json_encode($this->toArray(), $options); } /** * Get an iterator for the items. * * @return ArrayIterator */ public function getIterator() { return new ArrayIterator($this->items); } /** * Get a CachingIterator instance. * * @param integer $flags Caching iterator flags * * @return CachingIterator */ public function getCachingIterator($flags = CachingIterator::CALL_TOSTRING) { return new CachingIterator($this->getIterator(), $flags); } /** * Count the number of items in the collection. * * @return int */ public function count() { return count($this->items); } /** * Determine if an item exists at an offset. * * @param mixed $key * * @return bool */ public function offsetExists($key) { return array_key_exists($key, $this->items); } /** * Get an item at a given offset. * * @param mixed $key * * @return mixed */ public function offsetGet($key) { return $this->items[$key]; } /** * Set the item at a given offset. * * @param mixed $key * @param mixed $value * * @return void */ public function offsetSet($key, $value) { if (is_null($key)) { $this->items[] = $value; } else { $this->items[$key] = $value; } } /** * Unset the item at a given offset. * * @param string $key * * @return void */ public function offsetUnset($key) { unset($this->items[$key]); } /** * Convert the collection to its string representation. * * @return string */ public function __toString() { return $this->toJson(); } /** * Get a value retrieving callback. * * @param string $value * * @return Closure */ protected function valueRetriever($value) { return function ($item) use ($value) { return is_object($item) ? $item->{$value} : array_get($item, $value); }; } /** * Results array of items from Collection. * * @param Collection|array $items * * @return array */ private function getArrayableItems($items) { if ($items instanceof Collection) { $items = $items->all(); } elseif (is_object($items) && method_exists($items, 'toArray')) { $items = $items->toArray(); } return $items; } }
| ver. 1.4 |
Github
|
.
| PHP 8.1.34 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка