Merge pull request #9843 from annando/no-filetag
Legacy file/category storage is removed
This commit is contained in:
		
				commit
				
					
						215c6ecc14
					
				
			
		
					 15 changed files with 153 additions and 333 deletions
				
			
		| 
						 | 
				
			
			@ -23,8 +23,8 @@ namespace Friendica\Content;
 | 
			
		|||
 | 
			
		||||
use Friendica\Database\DBA;
 | 
			
		||||
use Friendica\Model\Contact;
 | 
			
		||||
use Friendica\Model\FileTag;
 | 
			
		||||
use Friendica\Model\Tag;
 | 
			
		||||
use Friendica\Model\Post;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A content helper class for displaying items
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +64,7 @@ class Item
 | 
			
		|||
		$folders = [];
 | 
			
		||||
		$first = true;
 | 
			
		||||
 | 
			
		||||
		foreach (FileTag::fileToArray($item['file'] ?? '', 'category') as $savedFolderName) {
 | 
			
		||||
		foreach (Post\Category::getArrayByURIId($item['uri-id'], $item['uid'], Post\Category::CATEGORY) as $savedFolderName) {
 | 
			
		||||
			if (!empty($item['author-link'])) {
 | 
			
		||||
				$url = $item['author-link'] . "?category=" . rawurlencode($savedFolderName);
 | 
			
		||||
			} else {
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +85,7 @@ class Item
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		if (local_user() == $item['uid']) {
 | 
			
		||||
			foreach (FileTag::fileToArray($item['file'] ?? '') as $savedFolderName) {
 | 
			
		||||
			foreach (Post\Category::getArrayByURIId($item['uri-id'], $item['uid'], Post\Category::FILE) as $savedFolderName) {
 | 
			
		||||
				$folders[] = [
 | 
			
		||||
					'name' => $savedFolderName,
 | 
			
		||||
					'url' => "#",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,9 +27,9 @@ use Friendica\Core\Renderer;
 | 
			
		|||
use Friendica\Database\DBA;
 | 
			
		||||
use Friendica\DI;
 | 
			
		||||
use Friendica\Model\Contact;
 | 
			
		||||
use Friendica\Model\FileTag;
 | 
			
		||||
use Friendica\Model\Group;
 | 
			
		||||
use Friendica\Model\Item;
 | 
			
		||||
use Friendica\Model\Post;
 | 
			
		||||
use Friendica\Util\DateTimeFormat;
 | 
			
		||||
use Friendica\Util\Temporal;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -305,19 +305,10 @@ class Widget
 | 
			
		|||
			return '';
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$saved = DI::pConfig()->get(local_user(), 'system', 'filetags');
 | 
			
		||||
		if (!strlen($saved)) {
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$terms = [];
 | 
			
		||||
		foreach (FileTag::fileToArray($saved) as $savedFolderName) {
 | 
			
		||||
		foreach (Post\Category::getArray(local_user(), Post\Category::FILE) as $savedFolderName) {
 | 
			
		||||
			$terms[] = ['ref' => $savedFolderName, 'name' => $savedFolderName];
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		usort($terms, function ($a, $b) {
 | 
			
		||||
			return strcmp($a['name'], $b['name']);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		return self::filter(
 | 
			
		||||
			'file',
 | 
			
		||||
| 
						 | 
				
			
			@ -348,13 +339,8 @@ class Widget
 | 
			
		|||
			return '';
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$saved = DI::pConfig()->get($uid, 'system', 'filetags');
 | 
			
		||||
		if (!strlen($saved)) {
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$terms = array();
 | 
			
		||||
		foreach (FileTag::fileToArray($saved, 'category') as $savedFolderName) {
 | 
			
		||||
		foreach (Post\Category::getArray(local_user(), Post\Category::CATEGORY) as $savedFolderName) {
 | 
			
		||||
			$terms[] = ['ref' => $savedFolderName, 'name' => $savedFolderName];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,10 +21,6 @@
 | 
			
		|||
 | 
			
		||||
namespace Friendica\Model;
 | 
			
		||||
 | 
			
		||||
use Friendica\Database\DBA;
 | 
			
		||||
use Friendica\DI;
 | 
			
		||||
use Friendica\Model\Post\Category;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class handles FileTag related functions
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +38,7 @@ class FileTag
 | 
			
		|||
	 *
 | 
			
		||||
	 * @return string   The URL encoded string.
 | 
			
		||||
	 */
 | 
			
		||||
	public static function encode($s)
 | 
			
		||||
	private static function encode($s)
 | 
			
		||||
	{
 | 
			
		||||
		return str_replace(['<', '>', '[', ']'], ['%3c', '%3e', '%5b', '%5d'], $s);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -54,31 +50,11 @@ class FileTag
 | 
			
		|||
	 *
 | 
			
		||||
	 * @return string   The decoded string.
 | 
			
		||||
	 */
 | 
			
		||||
	public static function decode($s)
 | 
			
		||||
	private static function decode($s)
 | 
			
		||||
	{
 | 
			
		||||
		return str_replace(['%3c', '%3e', '%5b', '%5d'], ['<', '>', '[', ']'], $s);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Query files for tag
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string $table The table to be queired.
 | 
			
		||||
	 * @param string $s     The search term
 | 
			
		||||
	 * @param string $type  Optional file type.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return string       Query string.
 | 
			
		||||
	 */
 | 
			
		||||
	public static function fileQuery($table, $s, $type = 'file')
 | 
			
		||||
	{
 | 
			
		||||
		if ($type == 'file') {
 | 
			
		||||
			$str = preg_quote('[' . str_replace('%', '%%', self::encode($s)) . ']');
 | 
			
		||||
		} else {
 | 
			
		||||
			$str = preg_quote('<' . str_replace('%', '%%', self::encode($s)) . '>');
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return " AND " . (($table) ? DBA::escape($table) . '.' : '') . "file regexp '" . DBA::escape($str) . "' ";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get file tags from array
 | 
			
		||||
	 *
 | 
			
		||||
| 
						 | 
				
			
			@ -155,167 +131,4 @@ class FileTag
 | 
			
		|||
 | 
			
		||||
		return self::arrayToFile($list_array, $type);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Get list from file tags
 | 
			
		||||
	 *
 | 
			
		||||
	 * ex. given <music><video>[friends], return music,video or friends
 | 
			
		||||
	 * @param string $file File tags
 | 
			
		||||
	 * @param string $type Optional file type.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return string       Comma delimited list of tag names.
 | 
			
		||||
	 * @deprecated since 2019.06 use fileToArray() instead
 | 
			
		||||
	 */
 | 
			
		||||
	public static function fileToList(string $file, $type = 'file')
 | 
			
		||||
	{
 | 
			
		||||
		return implode(',', self::fileToArray($file, $type));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Update file tags in PConfig
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param int    $uid      Unique Identity.
 | 
			
		||||
	 * @param string $file_old Categories previously associated with an item
 | 
			
		||||
	 * @param string $file_new New list of categories for an item
 | 
			
		||||
	 * @param string $type     Optional file type.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return boolean          A value indicating success or failure.
 | 
			
		||||
	 * @throws \Exception
 | 
			
		||||
	 */
 | 
			
		||||
	public static function updatePconfig(int $uid, string $file_old, string $file_new, string $type = 'file')
 | 
			
		||||
	{
 | 
			
		||||
		if (!intval($uid)) {
 | 
			
		||||
			return false;
 | 
			
		||||
		} elseif ($file_old == $file_new) {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$saved = DI::pConfig()->get($uid, 'system', 'filetags');
 | 
			
		||||
 | 
			
		||||
		if (strlen($saved)) {
 | 
			
		||||
			if ($type == 'file') {
 | 
			
		||||
				$lbracket = '[';
 | 
			
		||||
				$rbracket = ']';
 | 
			
		||||
				$termtype = Category::FILE;
 | 
			
		||||
			} else {
 | 
			
		||||
				$lbracket = '<';
 | 
			
		||||
				$rbracket = '>';
 | 
			
		||||
				$termtype = Category::CATEGORY;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			$filetags_updated = $saved;
 | 
			
		||||
 | 
			
		||||
			// check for new tags to be added as filetags in pconfig
 | 
			
		||||
			$new_tags = [];
 | 
			
		||||
			foreach (self::fileToArray($file_new, $type) as $tag) {
 | 
			
		||||
				if (!stristr($saved, $lbracket . self::encode($tag) . $rbracket)) {
 | 
			
		||||
					$new_tags[] = $tag;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			$filetags_updated .= self::arrayToFile($new_tags, $type);
 | 
			
		||||
 | 
			
		||||
			// check for deleted tags to be removed from filetags in pconfig
 | 
			
		||||
			$deleted_tags = [];
 | 
			
		||||
			foreach (self::fileToArray($file_old, $type) as $tag) {
 | 
			
		||||
				if (!stristr($file_new, $lbracket . self::encode($tag) . $rbracket)) {
 | 
			
		||||
					$deleted_tags[] = $tag;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			foreach ($deleted_tags as $key => $tag) {
 | 
			
		||||
				if (DBA::exists('category-view', ['name' => $tag, 'type' => $termtype, 'uid' => $uid])) {
 | 
			
		||||
					unset($deleted_tags[$key]);
 | 
			
		||||
				} else {
 | 
			
		||||
					$filetags_updated = str_replace($lbracket . self::encode($tag) . $rbracket, '', $filetags_updated);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if ($saved != $filetags_updated) {
 | 
			
		||||
				DI::pConfig()->set($uid, 'system', 'filetags', $filetags_updated);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		} elseif (strlen($file_new)) {
 | 
			
		||||
			DI::pConfig()->set($uid, 'system', 'filetags', $file_new);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Add tag to file
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param int    $uid     Unique identity.
 | 
			
		||||
	 * @param int    $item_id Item identity.
 | 
			
		||||
	 * @param string $file    File tag.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return boolean      A value indicating success or failure.
 | 
			
		||||
	 * @throws \Friendica\Network\HTTPException\InternalServerErrorException
 | 
			
		||||
	 */
 | 
			
		||||
	public static function saveFile($uid, $item_id, $file)
 | 
			
		||||
	{
 | 
			
		||||
		if (!intval($uid)) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$item = Post::selectFirst(['file'], ['id' => $item_id, 'uid' => $uid]);
 | 
			
		||||
		if (DBA::isResult($item)) {
 | 
			
		||||
			if (!stristr($item['file'], '[' . self::encode($file) . ']')) {
 | 
			
		||||
				$fields = ['file' => $item['file'] . '[' . self::encode($file) . ']'];
 | 
			
		||||
				Item::update($fields, ['id' => $item_id]);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			$saved = DI::pConfig()->get($uid, 'system', 'filetags');
 | 
			
		||||
 | 
			
		||||
			if (!strlen($saved) || !stristr($saved, '[' . self::encode($file) . ']')) {
 | 
			
		||||
				DI::pConfig()->set($uid, 'system', 'filetags', $saved . '[' . self::encode($file) . ']');
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Remove tag from file
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param int     $uid     Unique identity.
 | 
			
		||||
	 * @param int     $item_id Item identity.
 | 
			
		||||
	 * @param string  $file    File tag.
 | 
			
		||||
	 * @param boolean $cat     Optional value indicating the term type (i.e. Category or File)
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return boolean      A value indicating success or failure.
 | 
			
		||||
	 * @throws \Friendica\Network\HTTPException\InternalServerErrorException
 | 
			
		||||
	 */
 | 
			
		||||
	public static function unsaveFile($uid, $item_id, $file, $cat = false)
 | 
			
		||||
	{
 | 
			
		||||
		if (!intval($uid)) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ($cat == true) {
 | 
			
		||||
			$pattern = '<' . self::encode($file) . '>';
 | 
			
		||||
			$termtype = Category::CATEGORY;
 | 
			
		||||
		} else {
 | 
			
		||||
			$pattern = '[' . self::encode($file) . ']';
 | 
			
		||||
			$termtype = Category::FILE;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$item = Post::selectFirst(['file'], ['id' => $item_id, 'uid' => $uid]);
 | 
			
		||||
 | 
			
		||||
		if (!DBA::isResult($item)) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$fields = ['file' => str_replace($pattern, '', $item['file'])];
 | 
			
		||||
 | 
			
		||||
		Item::update($fields, ['id' => $item_id]);
 | 
			
		||||
 | 
			
		||||
		if (!DBA::exists('category-view', ['name' => $file, 'type' => $termtype, 'uid' => $uid])) {
 | 
			
		||||
			$saved = DI::pConfig()->get($uid, 'system', 'filetags');
 | 
			
		||||
			DI::pConfig()->set($uid, 'system', 'filetags', str_replace($pattern, '', $saved));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,7 +75,7 @@ class Item
 | 
			
		|||
	const DISPLAY_FIELDLIST = [
 | 
			
		||||
		'uid', 'id', 'parent', 'uri-id', 'uri', 'thr-parent', 'parent-uri', 'guid', 'network', 'gravity',
 | 
			
		||||
		'commented', 'created', 'edited', 'received', 'verb', 'object-type', 'postopts', 'plink',
 | 
			
		||||
		'wall', 'private', 'starred', 'origin', 'title', 'body', 'file', 'language',
 | 
			
		||||
		'wall', 'private', 'starred', 'origin', 'title', 'body', 'language',
 | 
			
		||||
		'content-warning', 'location', 'coord', 'app', 'rendered-hash', 'rendered-html', 'object',
 | 
			
		||||
		'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'item_id',
 | 
			
		||||
		'author-id', 'author-link', 'author-name', 'author-avatar', 'author-network',
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +112,7 @@ class Item
 | 
			
		|||
			'contact-id', 'type', 'wall', 'gravity', 'extid', 'psid',
 | 
			
		||||
			'created', 'edited', 'commented', 'received', 'changed', 'verb',
 | 
			
		||||
			'postopts', 'plink', 'resource-id', 'event-id', 'inform',
 | 
			
		||||
			'file', 'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'post-type',
 | 
			
		||||
			'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'post-type',
 | 
			
		||||
			'private', 'pubmail', 'moderated', 'visible', 'starred', 'bookmark',
 | 
			
		||||
			'unseen', 'deleted', 'origin', 'forum_mode', 'mention', 'global', 'network',
 | 
			
		||||
			'title', 'content-warning', 'body', 'location', 'coord', 'app',
 | 
			
		||||
| 
						 | 
				
			
			@ -203,17 +203,13 @@ class Item
 | 
			
		|||
		// We cannot simply expand the condition to check for origin entries
 | 
			
		||||
		// The condition needn't to be a simple array but could be a complex condition.
 | 
			
		||||
		// And we have to execute this query before the update to ensure to fetch the same data.
 | 
			
		||||
		$items = DBA::select('item', ['id', 'origin', 'uri', 'uri-id', 'uid', 'file'], $condition);
 | 
			
		||||
		$items = DBA::select('item', ['id', 'origin', 'uri', 'uri-id', 'uid'], $condition);
 | 
			
		||||
 | 
			
		||||
		$content_fields = [];
 | 
			
		||||
		foreach (array_merge(self::CONTENT_FIELDLIST, self::MIXED_CONTENT_FIELDLIST) as $field) {
 | 
			
		||||
			if (isset($fields[$field])) {
 | 
			
		||||
				$content_fields[$field] = $fields[$field];
 | 
			
		||||
				if (in_array($field, self::CONTENT_FIELDLIST)) {
 | 
			
		||||
					unset($fields[$field]);
 | 
			
		||||
				} else {
 | 
			
		||||
					$fields[$field] = null;
 | 
			
		||||
				}
 | 
			
		||||
				unset($fields[$field]);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -221,14 +217,12 @@ class Item
 | 
			
		|||
 | 
			
		||||
		$clear_fields = ['bookmark', 'type', 'author-name', 'author-avatar', 'author-link', 'owner-name', 'owner-avatar', 'owner-link', 'postopts', 'inform'];
 | 
			
		||||
		foreach ($clear_fields as $field) {
 | 
			
		||||
			if (array_key_exists($field, $fields)) {
 | 
			
		||||
				$fields[$field] = null;
 | 
			
		||||
			}
 | 
			
		||||
			unset($fields[$field]);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (array_key_exists('file', $fields)) {
 | 
			
		||||
			$files = $fields['file'];
 | 
			
		||||
			$fields['file'] = null;
 | 
			
		||||
			unset($fields['file']);
 | 
			
		||||
		} else {
 | 
			
		||||
			$files = null;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -269,9 +263,6 @@ class Item
 | 
			
		|||
 | 
			
		||||
			if (!is_null($files)) {
 | 
			
		||||
				Post\Category::storeTextByURIId($item['uri-id'], $item['uid'], $files);
 | 
			
		||||
				if (!empty($item['file'])) {
 | 
			
		||||
					DBA::update('item', ['file' => ''], ['id' => $item['id']]);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (!empty($fields['attach'])) {
 | 
			
		||||
| 
						 | 
				
			
			@ -358,7 +349,7 @@ class Item
 | 
			
		|||
		Logger::info('Mark item for deletion by id', ['id' => $item_id, 'callstack' => System::callstack()]);
 | 
			
		||||
		// locate item to be deleted
 | 
			
		||||
		$fields = ['id', 'uri', 'uri-id', 'uid', 'parent', 'parent-uri', 'origin',
 | 
			
		||||
			'deleted', 'file', 'resource-id', 'event-id',
 | 
			
		||||
			'deleted', 'resource-id', 'event-id',
 | 
			
		||||
			'verb', 'object-type', 'object', 'target', 'contact-id', 'psid', 'gravity'];
 | 
			
		||||
		$item = Post::selectFirst($fields, ['id' => $item_id]);
 | 
			
		||||
		if (!DBA::isResult($item)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -377,25 +368,7 @@ class Item
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		// clean up categories and tags so they don't end up as orphans
 | 
			
		||||
 | 
			
		||||
		$matches = [];
 | 
			
		||||
		$cnt = preg_match_all('/<(.*?)>/', $item['file'], $matches, PREG_SET_ORDER);
 | 
			
		||||
 | 
			
		||||
		if ($cnt) {
 | 
			
		||||
			foreach ($matches as $mtch) {
 | 
			
		||||
				FileTag::unsaveFile($item['uid'], $item['id'], $mtch[1],true);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$matches = [];
 | 
			
		||||
 | 
			
		||||
		$cnt = preg_match_all('/\[(.*?)\]/', $item['file'], $matches, PREG_SET_ORDER);
 | 
			
		||||
 | 
			
		||||
		if ($cnt) {
 | 
			
		||||
			foreach ($matches as $mtch) {
 | 
			
		||||
				FileTag::unsaveFile($item['uid'], $item['id'], $mtch[1],false);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		Post\Category::deleteByURIId($item['uri-id'], $item['uid']);
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * If item is a link to a photo resource, nuke all the associated photos
 | 
			
		||||
| 
						 | 
				
			
			@ -2363,7 +2336,7 @@ class Item
 | 
			
		|||
		$condition[0] .= " AND `received` < UTC_TIMESTAMP() - INTERVAL ? DAY";
 | 
			
		||||
		$condition[] = $days;
 | 
			
		||||
 | 
			
		||||
		$items = Post::select(['file', 'resource-id', 'starred', 'type', 'id', 'post-type'], $condition);
 | 
			
		||||
		$items = Post::select(['resource-id', 'starred', 'type', 'id', 'post-type', 'uid', 'uri-id'], $condition);
 | 
			
		||||
 | 
			
		||||
		if (!DBA::isResult($items)) {
 | 
			
		||||
			return;
 | 
			
		||||
| 
						 | 
				
			
			@ -2386,8 +2359,7 @@ class Item
 | 
			
		|||
 | 
			
		||||
		while ($item = Post::fetch($items)) {
 | 
			
		||||
			// don't expire filed items
 | 
			
		||||
 | 
			
		||||
			if (strpos($item['file'], '[') !== false) {
 | 
			
		||||
			if (DBA::exists('post-category', ['uri-id' => $item['uri-id'], 'uid' => $item['uid'], 'type' => Post\Category::FILE])) {
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,22 +63,6 @@ class Post
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!array_key_exists('verb', $row) || in_array($row['verb'], ['', Activity::POST, Activity::SHARE])) {
 | 
			
		||||
			// Build the file string out of the term entries
 | 
			
		||||
			if (array_key_exists('file', $row)) {
 | 
			
		||||
				if ($row['internal-file-count'] > 0) {
 | 
			
		||||
					$row['file'] = Post\Category::getTextByURIId($row['internal-uri-id'], $row['internal-uid']);
 | 
			
		||||
				} else {
 | 
			
		||||
					$row['file'] = '';
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Remove internal fields
 | 
			
		||||
		unset($row['internal-file-count']);
 | 
			
		||||
		unset($row['internal-uri-id']);
 | 
			
		||||
		unset($row['internal-uid']);
 | 
			
		||||
 | 
			
		||||
		return $row;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -213,7 +197,6 @@ class Post
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$selected = array_merge($selected, ['internal-uri-id', 'internal-uid', 'internal-file-count']);
 | 
			
		||||
		$selected = array_unique($selected);
 | 
			
		||||
 | 
			
		||||
		return DBA::select($view, $selected, $condition, $params);
 | 
			
		||||
| 
						 | 
				
			
			@ -267,8 +250,6 @@ class Post
 | 
			
		|||
			$selected = Item::DISPLAY_FIELDLIST;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$selected = array_unique(array_merge($selected, ['internal-uri-id', 'internal-uid', 'internal-file-count']));
 | 
			
		||||
 | 
			
		||||
		$condition = DBA::mergeConditions($condition,
 | 
			
		||||
			["`visible` AND NOT `deleted` AND NOT `moderated`
 | 
			
		||||
			AND NOT `author-blocked` AND NOT `owner-blocked`
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,6 @@
 | 
			
		|||
namespace Friendica\Model\Post;
 | 
			
		||||
 | 
			
		||||
use Friendica\Database\DBA;
 | 
			
		||||
use Friendica\Model\Item;
 | 
			
		||||
use Friendica\Model\Post;
 | 
			
		||||
use Friendica\Model\Tag;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -38,11 +37,42 @@ class Category
 | 
			
		|||
    const CATEGORY          = 3;
 | 
			
		||||
    const FILE              = 5;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Delete all categories and files from a given uri-id and user
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param int $uri_id
 | 
			
		||||
	 * @param int $uid
 | 
			
		||||
	 * @return boolean success
 | 
			
		||||
	 * @throws \Exception
 | 
			
		||||
	 */
 | 
			
		||||
	public static function deleteByURIId(int $uri_id, int $uid)
 | 
			
		||||
	{
 | 
			
		||||
		return DBA::delete('post-category', ['uri-id' => $uri_id, 'uid' => $uid]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Delete all categories and files from a given uri-id and user
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param int $uri_id
 | 
			
		||||
	 * @param int $uid
 | 
			
		||||
	 * @return boolean success
 | 
			
		||||
	 * @throws \Exception
 | 
			
		||||
	 */
 | 
			
		||||
	public static function deleteFileByURIId(int $uri_id, int $uid, int $type, string $file)
 | 
			
		||||
	{
 | 
			
		||||
		$tagid = Tag::getID($file);
 | 
			
		||||
		if (empty($tagid)) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return DBA::delete('post-category', ['uri-id' => $uri_id, 'uid' => $uid, 'type' => $type, 'tid' => $tagid]);
 | 
			
		||||
	}
 | 
			
		||||
	/**
 | 
			
		||||
	 * Generates the legacy item.file field string from an item ID.
 | 
			
		||||
	 * Includes only file and category terms.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param int $item_id
 | 
			
		||||
	 * @param int $uri_id
 | 
			
		||||
	 * @param int $uid
 | 
			
		||||
	 * @return string
 | 
			
		||||
	 * @throws \Exception
 | 
			
		||||
	 */
 | 
			
		||||
| 
						 | 
				
			
			@ -62,6 +92,58 @@ class Category
 | 
			
		|||
		return $file_text;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Generates an array of files or categories of a given uri-id
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param int $uid
 | 
			
		||||
	 * @param int $type
 | 
			
		||||
	 * @return array
 | 
			
		||||
	 * @throws \Exception
 | 
			
		||||
	 */
 | 
			
		||||
	public static function getArray(int $uid, int $type)
 | 
			
		||||
	{
 | 
			
		||||
		$tags = DBA::selectToArray('category-view', ['name'], ['uid' => $uid, 'type' => $type],
 | 
			
		||||
			['group_by' => ['name'], 'order' => ['name']]);
 | 
			
		||||
		if (empty($tags)) {
 | 
			
		||||
			return [];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return array_column($tags, 'name');
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Generates an array of files or categories of a given uri-id
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param int $uri_id
 | 
			
		||||
	 * @param int $uid
 | 
			
		||||
	 * @param int $type
 | 
			
		||||
	 * @return array
 | 
			
		||||
	 * @throws \Exception
 | 
			
		||||
	 */
 | 
			
		||||
	public static function getArrayByURIId(int $uri_id, int $uid, int $type = self::CATEGORY)
 | 
			
		||||
	{
 | 
			
		||||
		$tags = DBA::selectToArray('category-view', ['type', 'name'], ['uri-id' => $uri_id, 'uid' => $uid, 'type' => $type]);
 | 
			
		||||
		if (empty($tags)) {
 | 
			
		||||
			return [];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return array_column($tags, 'name');
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Generates a comma separated list of files or categories
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param int $uri_id
 | 
			
		||||
	 * @param int $uid
 | 
			
		||||
	 * @param int $type
 | 
			
		||||
	 * @return string
 | 
			
		||||
	 * @throws \Exception
 | 
			
		||||
	 */
 | 
			
		||||
	public static function getCSVByURIId(int $uri_id, int $uid, int $type)
 | 
			
		||||
	{
 | 
			
		||||
		return implode(',', self::getArrayByURIId($uri_id, $uid, $type));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Inserts new terms for the provided item ID based on the legacy item.file field BBCode content.
 | 
			
		||||
	 * Deletes all previous file terms for the same item ID.
 | 
			
		||||
| 
						 | 
				
			
			@ -101,18 +183,23 @@ class Category
 | 
			
		|||
 | 
			
		||||
		if (preg_match_all("/\<(.*?)\>/ism", $files, $result)) {
 | 
			
		||||
			foreach ($result[1] as $file) {
 | 
			
		||||
				$tagid = Tag::getID($file);
 | 
			
		||||
				if (empty($tagid)) {
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				DBA::replace('post-category', [
 | 
			
		||||
					'uri-id' => $uri_id,
 | 
			
		||||
					'uid' => $uid,
 | 
			
		||||
					'type' => self::CATEGORY,
 | 
			
		||||
					'tid' => $tagid
 | 
			
		||||
				]);
 | 
			
		||||
				self::storeFileByURIId($uri_id, $uid, self::FILE, $file);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static function storeFileByURIId(int $uri_id, int $uid, int $type, string $file)
 | 
			
		||||
	{
 | 
			
		||||
		$tagid = Tag::getID($file);
 | 
			
		||||
		if (empty($tagid)) {
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return DBA::replace('post-category', [
 | 
			
		||||
			'uri-id' => $uri_id,
 | 
			
		||||
			'uid' => $uid,
 | 
			
		||||
			'type' => $type,
 | 
			
		||||
			'tid' => $tagid
 | 
			
		||||
		]);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,8 +22,9 @@
 | 
			
		|||
namespace Friendica\Module\Filer;
 | 
			
		||||
 | 
			
		||||
use Friendica\BaseModule;
 | 
			
		||||
use Friendica\Database\DBA;
 | 
			
		||||
use Friendica\DI;
 | 
			
		||||
use Friendica\Model\FileTag;
 | 
			
		||||
use Friendica\Model\Post;
 | 
			
		||||
use Friendica\Network\HTTPException;
 | 
			
		||||
use Friendica\Util\XML;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -46,26 +47,33 @@ class RemoveTag extends BaseModule
 | 
			
		|||
		$term = XML::unescape(trim($_GET['term'] ?? ''));
 | 
			
		||||
		$cat = XML::unescape(trim($_GET['cat'] ?? ''));
 | 
			
		||||
 | 
			
		||||
		$category = (($cat) ? true : false);
 | 
			
		||||
 | 
			
		||||
		if ($category) {
 | 
			
		||||
		if (!empty($cat)) {
 | 
			
		||||
			$type = Post\Category::CATEGORY;
 | 
			
		||||
			$term = $cat;
 | 
			
		||||
		} else {
 | 
			
		||||
			$type = Post\Category::FILE;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$logger->info('Filer - Remove Tag', [
 | 
			
		||||
			'term'     => $term,
 | 
			
		||||
			'item'     => $item_id,
 | 
			
		||||
			'category' => ($category ? 'true' : 'false')
 | 
			
		||||
			'term' => $term,
 | 
			
		||||
			'item' => $item_id,
 | 
			
		||||
			'type' => $type
 | 
			
		||||
		]);
 | 
			
		||||
 | 
			
		||||
		if ($item_id && strlen($term)) {
 | 
			
		||||
			if (!FileTag::unsaveFile(local_user(), $item_id, $term, $category)) {
 | 
			
		||||
			$item = Post::selectFirst(['uri-id'], ['id' => $item_id]);
 | 
			
		||||
			if (!DBA::isResult($item)) {
 | 
			
		||||
				return;				
 | 
			
		||||
			}
 | 
			
		||||
			if (!Post\Category::deleteFileByURIId($item['uri-id'], local_user(), $type, $term)) {
 | 
			
		||||
				notice(DI::l10n()->t('Item was not removed'));
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			notice(DI::l10n()->t('Item was not deleted'));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		DI::baseUrl()->redirect('network?file=' . rawurlencode($term));
 | 
			
		||||
		if ($type == Post\Category::FILE) {
 | 
			
		||||
			DI::baseUrl()->redirect('filed?file=' . rawurlencode($term));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,8 +23,10 @@ namespace Friendica\Module\Filer;
 | 
			
		|||
 | 
			
		||||
use Friendica\BaseModule;
 | 
			
		||||
use Friendica\Core\Renderer;
 | 
			
		||||
use Friendica\Database\DBA;
 | 
			
		||||
use Friendica\DI;
 | 
			
		||||
use Friendica\Model;
 | 
			
		||||
use Friendica\Network\HTTPException;
 | 
			
		||||
use Friendica\Util\XML;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -52,13 +54,15 @@ class SaveTag extends BaseModule
 | 
			
		|||
		$logger->info('filer', ['tag' => $term, 'item' => $item_id]);
 | 
			
		||||
 | 
			
		||||
		if ($item_id && strlen($term)) {
 | 
			
		||||
			// file item
 | 
			
		||||
			Model\FileTag::saveFile(local_user(), $item_id, $term);
 | 
			
		||||
			$item = Model\Post::selectFirst(['uri-id'], ['id' => $item_id]);
 | 
			
		||||
			if (!DBA::isResult($item)) {
 | 
			
		||||
				throw new HTTPException\NotFoundException();
 | 
			
		||||
			}
 | 
			
		||||
			Model\Post\Category::storeFileByURIId($item['uri-id'], local_user(), Model\Post\Category::FILE, $term);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// return filer dialog
 | 
			
		||||
		$filetags = DI::pConfig()->get(local_user(), 'system', 'filetags', '');
 | 
			
		||||
		$filetags = Model\FileTag::fileToArray($filetags);
 | 
			
		||||
		$filetags = Model\Post\Category::getArray(local_user(), Model\Post\Category::FILE);
 | 
			
		||||
 | 
			
		||||
		$tpl = Renderer::getMarkupTemplate("filer_dialog.tpl");
 | 
			
		||||
		echo Renderer::replaceMacros($tpl, [
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2508,14 +2508,14 @@ class DFRN
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		$condition = ['uri' => $uri, 'uid' => $importer["importer_uid"]];
 | 
			
		||||
		$item = Post::selectFirst(['id', 'parent', 'contact-id', 'file', 'deleted', 'gravity'], $condition);
 | 
			
		||||
		$item = Post::selectFirst(['id', 'parent', 'contact-id', 'uri-id', 'deleted', 'gravity'], $condition);
 | 
			
		||||
		if (!DBA::isResult($item)) {
 | 
			
		||||
			Logger::log("Item with uri " . $uri . " for user " . $importer["importer_uid"] . " wasn't found.", Logger::DEBUG);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (strstr($item['file'], '[')) {
 | 
			
		||||
			Logger::log("Item with uri " . $uri . " for user " . $importer["importer_uid"] . " is filed. So it won't be deleted.", Logger::DEBUG);
 | 
			
		||||
		if (DBA::exists('post-category', ['uri-id' => $item['uri-id'], 'uid' => $importer['importer_uid'], 'type' => Post\Category::FILE])) {
 | 
			
		||||
			Logger::notice("Item is filed. It won't be deleted.", ['uri' => $uri, 'uri-id' => $item['uri_id'], 'uid' => $importer["importer_uid"]]);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2526,7 +2526,7 @@ class Diaspora
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		// Fetch items that are about to be deleted
 | 
			
		||||
		$fields = ['uid', 'id', 'parent', 'author-link', 'file'];
 | 
			
		||||
		$fields = ['uid', 'id', 'parent', 'author-link', 'uri-id'];
 | 
			
		||||
 | 
			
		||||
		// When we receive a public retraction, we delete every item that we find.
 | 
			
		||||
		if ($importer['uid'] == 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2542,7 +2542,7 @@ class Diaspora
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		while ($item = Post::fetch($r)) {
 | 
			
		||||
			if (strstr($item['file'], '[')) {
 | 
			
		||||
			if (DBA::exists('post-category', ['uri-id' => $item['uri-id'], 'uid' => $item['uid'], 'type' => Post\Category::FILE])) {
 | 
			
		||||
				Logger::log("Target guid " . $target_guid . " for user " . $item['uid'] . " is filed. So it won't be deleted.", Logger::DEBUG);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue