forked from Public/pics
		
	
		
			
				
	
	
		
			225 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			225 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
/*****************************************************************************
 | 
						|
 * AssetIterator.php
 | 
						|
 * Contains model class AssetIterator.
 | 
						|
 *
 | 
						|
 * Kabuki CMS (C) 2013-2025, Aaron van Geffen
 | 
						|
 *****************************************************************************/
 | 
						|
 | 
						|
class AssetIterator implements Iterator
 | 
						|
{
 | 
						|
	private $direction;
 | 
						|
	private $return_format;
 | 
						|
	private $rowCount;
 | 
						|
 | 
						|
	private $assets_iterator;
 | 
						|
	private $meta_iterator;
 | 
						|
	private $thumbs_iterator;
 | 
						|
 | 
						|
	protected function __construct(PDOStatement $stmt_assets, PDOStatement $stmt_meta, PDOStatement $stmt_thumbs,
 | 
						|
		$return_format, $direction)
 | 
						|
	{
 | 
						|
		$this->direction = $direction;
 | 
						|
		$this->return_format = $return_format;
 | 
						|
		$this->rowCount = $stmt_assets->rowCount();
 | 
						|
 | 
						|
		$this->assets_iterator = new CachedPDOIterator($stmt_assets);
 | 
						|
		$this->assets_iterator->rewind();
 | 
						|
 | 
						|
		$this->meta_iterator = new CachedPDOIterator($stmt_meta);
 | 
						|
		$this->thumbs_iterator = new CachedPDOIterator($stmt_thumbs);
 | 
						|
	}
 | 
						|
 | 
						|
	public static function all()
 | 
						|
	{
 | 
						|
		return self::getByOptions();
 | 
						|
	}
 | 
						|
 | 
						|
	public function current(): mixed
 | 
						|
	{
 | 
						|
		$row = $this->assets_iterator->current();
 | 
						|
		if (!$row)
 | 
						|
			return $row;
 | 
						|
 | 
						|
		// Collect metadata
 | 
						|
		$row['meta'] = [];
 | 
						|
		$this->meta_iterator->rewind();
 | 
						|
		foreach ($this->meta_iterator as $meta)
 | 
						|
		{
 | 
						|
			if ($meta['id_asset'] != $row['id_asset'])
 | 
						|
				continue;
 | 
						|
 | 
						|
			$row['meta'][$meta['variable']] = $meta['value'];
 | 
						|
		}
 | 
						|
 | 
						|
		// Collect thumbnails
 | 
						|
		$row['thumbnails'] = [];
 | 
						|
		$this->thumbs_iterator->rewind();
 | 
						|
		foreach ($this->thumbs_iterator as $thumb)
 | 
						|
		{
 | 
						|
			if ($thumb['id_asset'] != $row['id_asset'])
 | 
						|
				continue;
 | 
						|
 | 
						|
			$row['thumbnails'][$thumb['selector']] = $thumb['filename'];
 | 
						|
		}
 | 
						|
 | 
						|
		if ($this->return_format === 'object')
 | 
						|
			return new Asset($row);
 | 
						|
		else
 | 
						|
			return $row;
 | 
						|
	}
 | 
						|
 | 
						|
	public static function getByOptions(array $options = [], $return_count = false, $return_format = 'object')
 | 
						|
	{
 | 
						|
		$params = [
 | 
						|
			'limit' => isset($options['limit']) ? $options['limit'] : 0,
 | 
						|
			'order' => isset($options['order']) && in_array($options['order'], ['id_asset', 'subdir', 'filename', 'title',
 | 
						|
				'mime_type', 'image_width', 'image_height', 'date_captured']) ? $options['order'] : 'id_asset',
 | 
						|
			'direction' => isset($options['direction']) ? $options['direction'] : 'asc',
 | 
						|
		];
 | 
						|
 | 
						|
		if (isset($options['offset']))
 | 
						|
			$params['offset'] = $options['offset'];
 | 
						|
		elseif (isset($options['page']) && $options['page'] >= 1)
 | 
						|
			$params['offset'] = $params['limit'] * ($options['page'] - 1);
 | 
						|
		else
 | 
						|
			$params['offset'] = 0;
 | 
						|
 | 
						|
		$where = [];
 | 
						|
 | 
						|
		if (isset($options['mime_type']))
 | 
						|
		{
 | 
						|
			$params['mime_type'] = $options['mime_type'];
 | 
						|
			if (is_array($options['mime_type']))
 | 
						|
				$where[] = 'a.mimetype IN(@mime_type)';
 | 
						|
			else
 | 
						|
				$where[] = 'a.mimetype = :mime_type';
 | 
						|
		}
 | 
						|
		if (isset($options['id_user_uploaded']))
 | 
						|
		{
 | 
						|
			$params['id_user_uploaded'] = $options['id_user_uploaded'];
 | 
						|
			$where[] = 'id_user_uploaded = {int:id_user_uploaded}';
 | 
						|
		}
 | 
						|
		if (isset($options['id_tag']))
 | 
						|
		{
 | 
						|
			$params['id_tag'] = $options['id_tag'];
 | 
						|
			$where[] = 'id_asset IN(
 | 
						|
				SELECT l.id_asset
 | 
						|
				FROM assets_tags AS l
 | 
						|
				WHERE l.id_tag = :id_tag)';
 | 
						|
		}
 | 
						|
		elseif (isset($options['tag']))
 | 
						|
		{
 | 
						|
			$params['tag'] = $options['tag'];
 | 
						|
			$where[] = 'id_asset IN(
 | 
						|
				SELECT l.id_asset
 | 
						|
				FROM assets_tags AS l
 | 
						|
				INNER JOIN tags AS t
 | 
						|
				ON l.id_tag = t.id_tag
 | 
						|
				WHERE t.slug = :tag)';
 | 
						|
		}
 | 
						|
 | 
						|
		// Make it valid SQL.
 | 
						|
		$order = 'a.' . $params['order'] . ' ' . ($params['direction'] == 'desc' ? 'DESC' : 'ASC');
 | 
						|
		$where = empty($where) ? '1' : implode(' AND ', $where);
 | 
						|
 | 
						|
		// And ... go!
 | 
						|
		$db = Registry::get('db');
 | 
						|
 | 
						|
		// Get a resource object for the assets.
 | 
						|
		$res_assets = $db->query('
 | 
						|
			SELECT a.*
 | 
						|
			FROM assets AS a
 | 
						|
			WHERE ' . $where . '
 | 
						|
			ORDER BY ' . $order . (!empty($params['limit']) ? '
 | 
						|
			LIMIT :offset, :limit' : ''),
 | 
						|
			$params);
 | 
						|
 | 
						|
		// Get a resource object for the asset meta.
 | 
						|
		$res_meta = $db->query('
 | 
						|
			SELECT id_asset, variable, value
 | 
						|
			FROM assets_meta
 | 
						|
			WHERE id_asset IN(
 | 
						|
				SELECT id_asset
 | 
						|
				FROM assets AS a
 | 
						|
				WHERE ' . $where . '
 | 
						|
			)
 | 
						|
			ORDER BY id_asset',
 | 
						|
			$params);
 | 
						|
 | 
						|
		// Get a resource object for the asset thumbs.
 | 
						|
		$res_thumbs = $db->query('
 | 
						|
			SELECT id_asset, filename,
 | 
						|
				CONCAT(
 | 
						|
					width,
 | 
						|
					:x,
 | 
						|
					height,
 | 
						|
					IF(mode != :empty1, CONCAT(:_, mode), :empty2)
 | 
						|
				) AS selector
 | 
						|
			FROM assets_thumbs
 | 
						|
			WHERE id_asset IN(
 | 
						|
				SELECT id_asset
 | 
						|
				FROM assets AS a
 | 
						|
				WHERE ' . $where . '
 | 
						|
			)
 | 
						|
			ORDER BY id_asset',
 | 
						|
			$params + [
 | 
						|
				'empty1' => '',
 | 
						|
				'empty2' => '',
 | 
						|
				'x' => 'x',
 | 
						|
				'_' => '_',
 | 
						|
			]);
 | 
						|
 | 
						|
		$iterator = new self($res_assets, $res_meta, $res_thumbs, $return_format, $params['direction']);
 | 
						|
 | 
						|
		// Returning total count, too?
 | 
						|
		if ($return_count)
 | 
						|
		{
 | 
						|
			$count = $db->queryValue('
 | 
						|
				SELECT COUNT(*)
 | 
						|
				FROM assets AS a
 | 
						|
				WHERE ' . $where,
 | 
						|
				$params);
 | 
						|
 | 
						|
			return [$iterator, $count];
 | 
						|
		}
 | 
						|
		else
 | 
						|
			return $iterator;
 | 
						|
	}
 | 
						|
 | 
						|
	public function key(): mixed
 | 
						|
	{
 | 
						|
		return $this->assets_iterator->key();
 | 
						|
	}
 | 
						|
 | 
						|
	public function isAscending(): bool
 | 
						|
	{
 | 
						|
		return $this->direction === 'asc';
 | 
						|
	}
 | 
						|
 | 
						|
	public function isDescending(): bool
 | 
						|
	{
 | 
						|
		return $this->direction === 'desc';
 | 
						|
	}
 | 
						|
 | 
						|
	public function next(): void
 | 
						|
	{
 | 
						|
		$this->assets_iterator->next();
 | 
						|
	}
 | 
						|
 | 
						|
	public function num(): int
 | 
						|
	{
 | 
						|
		return $this->rowCount;
 | 
						|
	}
 | 
						|
 | 
						|
	public function rewind(): void
 | 
						|
	{
 | 
						|
		$this->assets_iterator->rewind();
 | 
						|
	}
 | 
						|
 | 
						|
	public function valid(): bool
 | 
						|
	{
 | 
						|
		return $this->assets_iterator->valid();
 | 
						|
	}
 | 
						|
}
 |