Skip to content

Commit a06cc36

Browse files
committed
Lesson 22 immutable objects
1 parent da96f68 commit a06cc36

19 files changed

+914
-1
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ Este curso explica programación orientada a objetos desde cero, para verlo sól
6363

6464
21. [Iteración de objetos](https://styde.net/iteracion-de-objetos-en-php/) - 11:57
6565

66-
22. Objetos inmutables
66+
22. [Objetos inmutables](https://styde.net/objetos-inmutables-en-php/) - 21:29
6767

6868
23. Comparación entre objetos
6969

lesson22/composer.json

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "styde/oop",
3+
"description": "Proyecto demo para el curso de programacion orientada a objetos",
4+
"type": "project",
5+
"license": "MIT",
6+
"authors": [
7+
{
8+
"name": "Duilio Palacios",
9+
"email": "[email protected]"
10+
}
11+
],
12+
"require": {},
13+
"autoload": {
14+
"psr-4": {
15+
"Styde\\": "src/"
16+
}
17+
}
18+
}

lesson22/public/index.php

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
require '../vendor/autoload.php';
4+
5+
use Styde\User;
6+
use Styde\Food;
7+
use Styde\LunchBox;
8+
9+
$gordon = new User(['name' => 'Gordon']);
10+
11+
// Daughter
12+
$joanie = new User(['name' => 'Joanie']);
13+
14+
$lunchBox = new LunchBox(['Sandwich', 'Papas', 'Jugo de naranja', 'Manzana']);
15+
16+
$lunchBox = new LunchBox([
17+
new Food(['name' => 'Sandwich', 'beverage' => false]),
18+
new Food(['name' => 'Papas']),
19+
new Food(['name' => 'Jugo de naranja', 'beverage' => true]),
20+
new Food(['name' => 'Manzana']),
21+
new Food(['name' => 'Agua', 'beverage' => true]),
22+
]);
23+
24+
// House
25+
$joanie->setLunch($lunchBox);
26+
27+
// School
28+
$joanie->eatMeal();
29+
30+

lesson22/public/time.php

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
class Time {
4+
5+
protected $time = null;
6+
7+
public function __construct($time = null)
8+
{
9+
$this->time = $time ?: time();
10+
}
11+
12+
public function __toString()
13+
{
14+
return date('d/m/Y H:i:s', $this->time);
15+
}
16+
17+
public function tomorrow()
18+
{
19+
return new Time($this->time + 24*60*60);
20+
}
21+
22+
public function yesterday()
23+
{
24+
return new Time($this->time - 24*60*60);
25+
}
26+
}
27+
28+
$today = new Time();
29+
30+
$today2 = new Time();
31+
32+
33+
echo "<p>Hoy es {$today2}</p>";
34+
35+
$tomorrow = $today->tomorrow();
36+
37+
echo "<p>Mañana será {$tomorrow}</p>";
38+
39+
echo "<p>Pasado mañana será {$tomorrow->tomorrow()}</p>";
40+
41+
echo "<p>Ayer fue {$today->yesterday()}</p>";
42+
43+
44+
45+
46+

lesson22/src/Food.php

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Styde;
4+
5+
class Food extends Model {
6+
7+
public function getBeverageAttribute()
8+
{
9+
return $this->attributes['beverage'] ?? false;
10+
}
11+
12+
}

lesson22/src/HtmlNode.php

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
namespace Styde;
4+
5+
class HtmlNode
6+
{
7+
protected $tag;
8+
protected $content;
9+
protected $attributes = [];
10+
11+
public function __construct($tag, $content = null, $attributes = [])
12+
{
13+
$this->tag = $tag;
14+
$this->content = $content;
15+
$this->attributes = $attributes;
16+
}
17+
18+
public function __invoke($name, $default = null)
19+
{
20+
return $this->get($name, $default);
21+
}
22+
23+
public function get($name, $default = null)
24+
{
25+
return $this->attributes[$name] ?? $default;
26+
}
27+
28+
public static function __callStatic($method, array $args = [])
29+
{
30+
$content = isset($args[0]) ? $args[0] : null;
31+
32+
$attributes = isset($args[1]) ? $args[1] : [];
33+
34+
return new HtmlNode($method, $content, $attributes);
35+
}
36+
37+
public function __toString()
38+
{
39+
return $this->render();
40+
}
41+
42+
public function __call($method, array $args = [])
43+
{
44+
if (! isset ($args[0])) {
45+
throw new \Exception(
46+
"You forgot to pass the value to the attribute $method"
47+
);
48+
}
49+
50+
$this->attributes[$method] = $args[0];
51+
52+
return $this;
53+
}
54+
55+
public function render()
56+
{
57+
$result = "<{$this->tag} {$this->renderAttributes()}>";
58+
59+
if ($this->content != null) {
60+
$result .= $this->content;
61+
62+
$result .= "</{$this->tag}>";
63+
}
64+
65+
return $result;
66+
}
67+
68+
protected function renderAttributes()
69+
{
70+
$result = "";
71+
72+
foreach ($this->attributes as $name => $value)
73+
{
74+
$result .= sprintf(' %s="%s"', $name, $value);
75+
}
76+
77+
return $result;
78+
}
79+
}
80+
81+
82+

lesson22/src/LunchBox.php

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
namespace Styde;
4+
5+
class LunchBox implements \IteratorAggregate, \Countable
6+
{
7+
protected $food = [];
8+
9+
protected $original = true;
10+
11+
public function __construct(array $food = [])
12+
{
13+
$this->food = $food;
14+
}
15+
16+
public function __clone()
17+
{
18+
$this->original = false;
19+
}
20+
21+
public function all()
22+
{
23+
return $this->food;
24+
}
25+
26+
public function filter($callback)
27+
{
28+
return new static(array_filter($this->food, $callback));
29+
}
30+
31+
public function shift()
32+
{
33+
return array_shift($this->food);
34+
}
35+
36+
public function isEmpty()
37+
{
38+
return empty($this->food);
39+
}
40+
41+
public function getIterator()
42+
{
43+
return new \ArrayIterator($this->food);
44+
}
45+
46+
public function count()
47+
{
48+
return count($this->food);
49+
}
50+
}
51+
52+
53+

lesson22/src/Model.php

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
namespace Styde;
4+
5+
abstract class Model
6+
{
7+
protected $attributes = [];
8+
9+
public function __construct(array $attributes = [])
10+
{
11+
$this->fill($attributes);
12+
}
13+
14+
public function fill(array $attributes = [])
15+
{
16+
$this->attributes = $attributes;
17+
}
18+
19+
public function getAttributes()
20+
{
21+
return $this->attributes;
22+
}
23+
24+
public function getAttribute($name)
25+
{
26+
$value = $this->getAttributeValue($name);
27+
28+
if ($this->hasGetMutator($name)) {
29+
return $this->mutateAttribute($name, $value);
30+
}
31+
32+
return $value;
33+
}
34+
35+
protected function hasGetMutator($name)
36+
{
37+
return method_exists($this, 'get'.Str::studly($name).'Attribute');
38+
}
39+
40+
protected function mutateAttribute($name, $value)
41+
{
42+
return $this->{'get'.Str::studly($name).'Attribute'}($value);
43+
}
44+
45+
public function getAttributeValue($name)
46+
{
47+
if (array_key_exists($name, $this->attributes)) {
48+
return $this->attributes[$name];
49+
}
50+
}
51+
52+
public function setAttribute($name, $value)
53+
{
54+
$this->attributes[$name] = $value;
55+
}
56+
57+
public function __set($name, $value)
58+
{
59+
$this->setAttribute($name, $value);
60+
}
61+
62+
public function __get($name)
63+
{
64+
return $this->getAttribute($name);
65+
}
66+
67+
public function __isset($name)
68+
{
69+
return isset($this->attributes[$name]);
70+
}
71+
72+
public function __unset($name)
73+
{
74+
unset ($this->attributes[$name]);
75+
}
76+
}

lesson22/src/Str.php

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Styde;
4+
5+
class Str
6+
{
7+
public static function studly($value)
8+
{
9+
$result = ucwords(str_replace('_', ' ', $value));
10+
11+
return str_replace(' ', '', $result);
12+
}
13+
14+
public static function snake($value)
15+
{
16+
$result = preg_replace("@([A-Z])@", "_$1", $value);
17+
return strtolower(trim($result, '_'));
18+
}
19+
}

0 commit comments

Comments
 (0)