aboutsummaryrefslogtreecommitdiffstats
path: root/core/namespace/Item.php
blob: 60f7547a0e9206de2078c7127a322729abd16040 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
<?php
abstract class Item implements ItemInterface {
	protected $Database   = NULL;
	protected $Attribute  = NULL;
	protected $Reflection = NULL;

	abstract public function getURL();
	abstract public function getGUID();

	#===============================================================================
	# Abstract item constructor
	#===============================================================================
	public final function __construct($itemID, \Database $Database) {
		$this->Database = $Database;

		$this->Reflection = new ReflectionObject($this);

		$attribute = "{$this->Reflection->getNamespaceName()}\\Attribute";
		$exception = "{$this->Reflection->getNamespaceName()}\\Exception";

		#===============================================================================
		# Checking if item in database exists
		#===============================================================================
		$Statement = $Database->prepare(sprintf('SELECT * FROM %s WHERE id = ?', $attribute::TABLE));
		$Statement->execute([$itemID]);

		#===============================================================================
		# Checking if retrieving data failed
		#===============================================================================
		if(!$this->Attribute = $Statement->fetchObject($attribute)) {
			throw new $exception(sprintf('%s\\Item with ID %s does not exist', $this->Reflection->getNamespaceName(), (int) $itemID));
		}
	}

	#===============================================================================
	# Return attribute by name (short hand wrapper)
	#===============================================================================
	public function attr($attribute) {
		return $this->Attribute->get($attribute);
	}

	#===============================================================================
	# Return Attribute object
	#===============================================================================
	public final function getAttribute(): Attribute {
		return $this->Attribute;
	}

	#===============================================================================
	# Return unique ID
	#===============================================================================
	public final function getID(): int {
		return $this->Attribute->get('id');
	}

	#===============================================================================
	# Return pre-parsed content
	#===============================================================================
	public function getBody(): string {
		$content = preg_replace_callback('#\{(POST|PAGE|USER)\[([0-9]+)\]\}#', function($matches) {
			$namespace = ucfirst(strtolower($matches[1])).'\\Factory';

			try {
				$Item = $namespace::build($matches[2]);
				return $Item->getURL();
			} catch(Exception $Exception) {
				return '{undefined}';
			}
		}, $this->Attribute->get('body'));

		$content = preg_replace('#\{BASE\[\"([^"]+)\"\]\}#', \Application::getURL('$1'), $content);
		$content = preg_replace('#\{FILE\[\"([^"]+)\"\]\}#', \Application::getFileURL('$1'), $content);

		return $content;
	}

	#===============================================================================
	# Return parsed content
	#===============================================================================
	public function getHTML(): string {
		$item = "{$this->Reflection->getNamespaceName()}\\Item";

		$Parsedown = new Parsedown();
		$Parsedown->setUrlsLinked(FALSE);
		$content = $this->getBody();

		if(\Application::get($item::CONFIGURATION.'.EMOTICONS') === TRUE) {
			$content = parseEmoticons($content);
		}

		return $Parsedown->text($content);
	}

	#===============================================================================
	# Return attached files
	#===============================================================================
	public function getFiles(): array {
		if(preg_match_all('#\!\[(.*)\][ ]?(?:\n[ ]*)?\((.*)(\s[\'"](.*)[\'"])?\)#U', $this->getBody(), $matches)) {
			return array_map('htmlentities', $matches[2]);
		}

		return [];
	}

	#===============================================================================
	# Return parsed arguments
	#===============================================================================
	public function getArguments(): array {
		if($argv = $this->Attribute->get('argv')) {
			foreach(explode('|', $argv) as $delimeter) {
				$part = explode('=', $delimeter);

				$argumentK = $part[0] ?? NULL;
				$argumentV = $part[1] ?? TRUE;

				if(preg_match('#^[[:word:]]+$#', $argumentK)) {
					$arguments[strtoupper($argumentK)] = $argumentV;
				}
			}
		}

		return $arguments ?? [];
	}

	#===============================================================================
	# Return previous item ID
	#===============================================================================
	public function getPrevID(): int {
		$execute = 'SELECT id FROM %s WHERE time_insert < ? ORDER BY time_insert DESC LIMIT 1';

		$attribute = "{$this->Reflection->getNamespaceName()}\\Attribute";
		$Statement = $this->Database->prepare(sprintf($execute, $attribute::TABLE));

		if($Statement->execute([$this->Attribute->get('time_insert')])) {
			return $Statement->fetchColumn();
		}

		return 0;
	}

	#===============================================================================
	# Return next item ID
	#===============================================================================
	public function getNextID(): int {
		$execute = 'SELECT id FROM %s WHERE time_insert > ? ORDER BY time_insert ASC LIMIT 1';

		$attribute = "{$this->Reflection->getNamespaceName()}\\Attribute";
		$Statement = $this->Database->prepare(sprintf($execute, $attribute::TABLE));

		if($Statement->execute([$this->Attribute->get('time_insert')])) {
			return $Statement->fetchColumn();
		}

		return 0;
	}

	#===============================================================================
	# Return unique ID based on specific field comparison with value
	#===============================================================================
	public static function getIDByField($field, $value, \Database $Database): int {
		$attribute = (new ReflectionClass(get_called_class()))->getNamespaceName().'\\Attribute';
		$Statement = $Database->prepare('SELECT id FROM '.$attribute::TABLE." WHERE {$field} = ?");

		if($Statement->execute([$value])) {
			return $Statement->fetchColumn();
		}

		return 0;
	}

	#===============================================================================
	# Return Attribute instance based on field comparison with value
	#===============================================================================
	public static function getByField($field, $value, \Database $Database): Attribute {
		$exception = (new ReflectionClass(get_called_class()))->getNamespaceName().'\\Exception';
		$attribute = (new ReflectionClass(get_called_class()))->getNamespaceName().'\\Attribute';
		$Statement = $Database->prepare('SELECT * FROM '.$attribute::TABLE." WHERE {$field} = ?");

		if($Statement->execute([$value])) {
			if(!$Attribute = $Statement->fetchObject($attribute)) {
				throw new $exception(sprintf("Item with value %s on field %s does not exist.", $value, $field));
			}

			return $Attribute;
		}
	}
}
?>