Paperyard
Document.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Paperyard\Models;
4 
8 
9 class Document
10 {
12  const REGEX_TAG = '/^([ÄäÜüÖöß\sa-zA-Z0-9]+,)*[ÄäÜüÖöß\sa-zA-Z0-9]+$/';
13 
15  const REGEX_STRING = '/^[ÄäÜüÖöß\sa-zA-Z0-9]*$/';
16 
18  const REGEX_DATE = '/^(0[1-9]|[1-2][0-9]|3[0-1]).(0[1-9]|1[0-2]).(20\d{2})$/';
19 
21  const REGEX_PRICE = '/^\d+(\.\d{3})*(,\d{2})?$/';
22 
23 
25  const INDEX_DATE = 1;
26 
28  const INDEX_COMPANY = 2;
29 
31  const INDEX_SUBJECT = 3;
32 
34  const INDEX_RECIPIENT = 4;
35 
37  const INDEX_PRICE = 5;
38 
40  const INDEX_TAGS = 6;
41 
43  const INDEX_OLD_FILENAME = 7;
44 
45 
47  public $name;
48 
50  public $size;
51 
53  public $subject;
54 
56  public $tags;
57 
59  public $price;
60 
62  public $recipient;
63 
65  public $company;
66 
68  public $date;
69 
71  public $oldFilename;
72 
74  public $pages;
75 
77  public $identifier;
78 
80  public $hash;
81 
82  public $url;
83 
85  public $isConfirmed;
86 
88  private $fullPath;
89 
91  private $documentType;
92 
94  private $rawAttributes = [];
95 
97  private $errors = [];
98 
100  private $fillable = [
101  'document-subject' => 'subject',
102  'document-tags' => 'tags',
103  'document-price' => 'price',
104  'document-recipient' => 'recipient',
105  'document-company' => 'company',
106  'document-date' => 'date'
107  ];
108 
110  private $rules = [
111  'optional' => [
112  ['document-subject'],
113  ['document-tags'],
114  ['document-price'],
115  ['document-recipient'],
116  ['document-company'],
117  ['document-date']
118  ],
119  'regex' => [
120  ['document-subject', self::REGEX_STRING],
121  ['document-recipient', self::REGEX_STRING],
122  ['document-company', self::REGEX_STRING],
123  ['document-tags', self::REGEX_TAG],
124  ['document-price', self::REGEX_PRICE],
125  ['document-date', self::REGEX_DATE]
126  ]
127  ];
128 
130  private $labels = [
131  'document-subject' => 'Subject',
132  'document-tags' => 'Tags',
133  'document-price' => 'Price',
134  'document-recipient' => 'Recipient',
135  'document-company' => 'Company',
136  'document-date' => 'Date'
137  ];
138 
142  public function __construct($full_path)
143  {
144  // everything starts with the filename
145  $this->fullPath = $full_path;
146 
147  // might be handy later to have this info
148  $this->documentType = (pathinfo($this->fullPath, PATHINFO_EXTENSION) == "pdf" ? DocumentType::PDF : DocumentType::OTHER);
149 
150  // fill object with data
151  $this->name = basename($this->fullPath);
152  $this->size = $this->humanFilesize($full_path);
153  $this->hash = hash_file("sha256", $full_path);
154  $this->pages = $this->getNumberOfPages($full_path);
155  $this->identifier = base64_encode($full_path);
156  $this->url = $this->getUrl($full_path);
157 
158  $this->parseDataFromFilename();
159 
160  $this->isConfirmed = $this->isConfirmed();
161  }
162 
163  private function getUrl($full_path) {
164  $path = explode('/', $full_path);
165  unset($path[1]);
166  array_walk($path, function(&$part) {
167  $part = rawurlencode($part);
168  });
169  return implode('/', $path);
170  }
171 
172  private function parseDataFromFilename()
173  {
174  $this->date = $this->parseAttribute(self::INDEX_DATE);
175  $this->company = $this->parseAttribute(self::INDEX_COMPANY);
176  $this->subject = $this->parseAttribute(self::INDEX_SUBJECT);
177  $this->recipient = $this->parseAttribute(self::INDEX_RECIPIENT);
178  $this->price = $this->parseAttribute(self::INDEX_PRICE);
179  $this->tags = $this->parseAttribute(self::INDEX_TAGS);
180  $this->oldFilename = $this->parseAttribute(self::INDEX_OLD_FILENAME);
181  }
182 
188  public function toArray()
189  {
190  return get_object_vars($this);
191  }
192 
199  private function parseDate() {
200  return date_format(date_create($this->parseAttribute(self::INDEX_DATE)), 'd.m.Y');
201  }
202 
209  private function parseAttribute($attr)
210  {
211  // fill if still empty
212  if ($this->rawAttributes == []) {
213  preg_match('/^(.*?) - (.*?) - (.*?) \((.*?)\) \(EUR(.*?)\) \[(.*?)\] -- (.*?)(?:.pdf)$/', $this->name, $this->rawAttributes);
214  }
215 
216  if (!array_key_exists($attr, $this->rawAttributes)) {
217  return "";
218  }
219 
220  return $this->rawAttributes[$attr];
221  }
222 
229  private function getNumberOfPages($full_path)
230  {
231  $pdf = new PDFInfo($full_path);
232  return (int)$pdf->pages;
233  }
234 
243  private function humanFilesize($full_path, $decimals = 2)
244  {
245  $bytes = filesize($full_path);
246  $size = array('B','kB','MB','GB','TB','PB','EB','ZB','YB');
247  $factor = floor((strlen($bytes) - 1) / 3);
248  return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . ' ' . @$size[$factor];
249  }
250 
257  public function fill(array $attributes)
258  {
259  // remove "", null, 0, false and "0"
260  $attributes = array_filter($attributes);
261 
262  $this->validate($attributes);
263 
264  if (!empty($this->errors)) {
265  return $this->errors;
266  }
267 
268  // go through every mutable property
269  foreach ($this->fillable as $post_attribute => $obj_property) {
270  // check if property exists and has value in post attributes array
271  if (property_exists($this, $obj_property) && array_key_exists($post_attribute, $attributes)) {
272  if ($this->hasMutator($obj_property)) {
273  $mutator = $this->mutatorFor($obj_property);
274  $this->{$obj_property} = $this->{$mutator}($attributes[$post_attribute]);
275  } else {
276  $this->{$obj_property} = $attributes[$post_attribute];
277  }
278  }
279  }
280 
281  return true;
282  }
283 
290  private function hasMutator($attribute)
291  {
292  return method_exists($this, $this->mutatorFor($attribute));
293  }
294 
302  private function mutatorFor($attribute)
303  {
304  return 'set' . ucfirst($attribute) . 'Attribute';
305  }
306 
314  private function setDateAttribute($date)
315  {
316  return \DateTime::createFromFormat("d.m.Y", $date)->format('Ymd');
317  }
318 
326  private function setPriceAttribute($price)
327  {
328  $dotless = str_replace(".", "", $price);
329 
330  if (strpos($dotless, ",") === false) {
331  return $dotless . ",00";
332  }
333 
334  return $dotless;
335  }
336 
344  private function setTagsAttribute($tags)
345  {
346  if (empty($tags)) {
347  return 'nt';
348  }
349 
350  return $tags;
351  }
352 
353  public function save()
354  {
355  $format = '%d - %s - %s (%s) (EUR%s) [%s] -- %s.pdf';
356  $filename = sprintf(
357  $format,
358  $this->date,
359  $this->company,
360  $this->subject,
361  $this->recipient,
362  $this->price,
363  $this->tags,
364  $this->oldFilename);
365 
366  $dir = dirname($this->fullPath);
367  $new_fullpath = $dir . DIRECTORY_SEPARATOR . $filename;
368  rename($this->fullPath, $new_fullpath);
369  $this->fullPath = $new_fullpath;
370  }
371 
372  public function confirm()
373  {
374  // tag string to array
375  $tags = explode(',', $this->tags);
376 
377  // trim
378  $trimmed = array_map('trim', $tags);
379 
380  // cleaning - remove nt and ok (if present)
381  $cleaned = array_diff($trimmed, ['nt', 'ok']);
382 
383  // confirm - adding ok
384  $cleaned[] = 'ok';
385 
386  // glue
387  $this->tags = implode(',', $cleaned);
388  }
389 
390  private function isConfirmed()
391  {
392  // tag string to array
393  $tags = explode(',', $this->tags);
394 
395  return in_array('ok', $tags);
396  }
397 
401  private function validate(array $attributes)
402  {
403  // new validator object
404  $validator = new Validator($attributes);
405 
406  // pass rules
407  $validator->rules($this->rules);
408 
409  // add labels (don't show internal names)
410  $validator->labels($this->labels);
411 
412  // check rules
413  if(!$validator->validate()) {
414  $this->errors = $validator->errors();
415  }
416  }
417 
424  public static function findAll(array $paths)
425  {
426  array_walk($paths, function (&$path) {
427  $path = glob($path);
428  });
429 
430  $pdfs = Document::flatten($paths);
431 
432  array_walk($pdfs, function (&$pdf) {
433  $pdf = (new \Paperyard\Models\Document($pdf))->toArray();
434  });
435 
436  return $pdfs;
437  }
438 
439  private static function flatten(array $array) {
440  $return = array();
441  array_walk_recursive($array, function($a) use (&$return) { $return[] = $a; });
442  return $return;
443  }
444 }
getNumberOfPages($full_path)
Definition: Document.php:229
validate(array $attributes)
Definition: Document.php:401
$pdfs
humanFilesize($full_path, $decimals=2)
Definition: Document.php:243
fill(array $attributes)
Definition: Document.php:257
static findAll(array $paths)
Definition: Document.php:424
static flatten(array $array)
Definition: Document.php:439