Skip to content

Commit b7f532c

Browse files
committed
Add format methods
1 parent 67c7dcd commit b7f532c

9 files changed

+559
-465
lines changed

README.md

+69-223
Original file line numberDiff line numberDiff line change
@@ -1,293 +1,139 @@
1+
# Darn Tidy Object (DTO)
12

2-
# MaplePHP - Data Transfer Object (DTO)
3+
DTO stands for **Darn Tidy Object**, a playful twist on the traditional Data Transfer Object. But this isn’t your average DTO. It’s a fully-loaded toolkit for **traversing, transforming, and tidying up structured data** in PHP with style, power, and simplicity.
34

4-
The MaplePHP DTO library simplifies working with structured data in PHP by wrapping it into objects. This allows easy traversal and transformation through a chainable interface, ensuring consistent, safe data handling and reducing the risk of direct data manipulation.
55

6-
- **Encapsulation**: Encapsulates data within objects.
7-
- **Immutability**: Ensures data integrity by preventing accidental modification.
8-
- **Validation**: Facilitates data validation, ensuring the data conforms to specific types or formats.
9-
- **Data Transformation**: Easily modify and format data using built-in methods.
10-
- **Low Coupling**: Promotes separation of concerns, reducing dependencies between different parts of your code.
11-
- **Improved Readability**: Makes code cleaner and easier to understand.
12-
- **Simplified Testing**: DTOs are easier to test, as they contain only data and transformation logic.
6+
## 📦 Installation
137

14-
---
15-
16-
**Note:** MaplePHP DTO also includes polyfill classes for Multibyte String and Iconv support.
17-
18-
## **1. Creating a DTO Object**
19-
20-
The simplest way to start using **MaplePHP DTO** is with the `Traverse` class:
21-
22-
```php
23-
use MaplePHP\DTO\Traverse;
24-
25-
$obj = Traverse::value([
26-
"firstname" => "<em>daniel</em>",
27-
"lastname" => "doe",
28-
"price" => "1999.99",
29-
"date" => "2023-08-21 14:35:12",
30-
"feed" => [
31-
"t1" => ["firstname" => "<em>john 1</em>", "lastname" => "doe-1", 'salary' => 40000],
32-
"t2" => ["firstname" => "<em>jane 2</em>", "lastname" => "doe-2", 'salary' => 20000]
33-
]
34-
]);
8+
```bash
9+
composer require maplephp/dto
3510
```
3611

37-
Now, `$obj` behaves like an object where you can access its properties directly.
12+
## 📦 Installation
3813

39-
---
40-
41-
## **2. Accessing Data**
42-
43-
### **Direct Property Access**
44-
45-
```php
46-
echo $obj->firstname;
47-
// Output: <em>daniel</em>
14+
```bash
15+
composer require maplephp/dto
4816
```
4917

50-
### **Safe Fallback for Missing Values**
18+
## 📘 Documentation
19+
- [Why DTO?](http://localhost:3000/docs/intro#why-dto)
20+
- [Traverse Collection](http://localhost:3000/docs/traverse)
21+
- [Format string](http://localhost:3000/docs/format-string)
22+
- [Format Number](http://localhost:3000/docs/format-number)
23+
- [Format Clock](http://localhost:3000/docs/format-clock)
24+
- [Format Dom](http://localhost:3000/docs/format-dom)
5125

52-
```php
53-
echo $obj->feed->t1->doNotExist->fallback('lorem')->strUcFirst();
54-
// Output: Lorem
55-
```
5626

57-
---
27+
## How It Works
5828

59-
## **3. Working with Collections**
29+
DTO wraps your data arrays into a powerful, fluent object structure. Instead of cluttered array access, your code becomes expressive and self-documenting.
6030

61-
### **Iterating Over Arrays**
31+
### Before DTO
6232

6333
```php
64-
foreach ($obj->feed->fetch() as $row) {
65-
echo $row->firstname->strStripTags()->strUcFirst();
66-
}
67-
// Output:
68-
// John 1
69-
// Jane 2
34+
$name = isset($data['user']['profile']['name'])
35+
? ucfirst(strip_tags($data['user']['profile']['name']))
36+
: 'Guest';
7037
```
7138

72-
### **Filtering Data (`filter`)**
73-
74-
Filters an array based on a callback function.
39+
### With DTO
7540

7641
```php
77-
$filtered = $obj->feed->filter(fn($row) => $row->salary->get() > 30000);
78-
echo $filtered->count();
79-
// Output: 1
42+
$name = $obj->user->profile->name
43+
->strStripTags()
44+
->strUcFirst()
45+
->fallback('Guest')
46+
->get();
8047
```
8148

82-
### **Finding Specific Values**
83-
84-
```php
85-
echo $obj->shopList->search('cheese');
86-
// Output: 3
87-
```
88-
89-
```php
90-
echo $obj->feed->pluck('lastname')->toArray()[1];
91-
// Output: doe-2
92-
```
49+
Much tidier, right?
9350

9451
---
9552

96-
## **4. Transforming Collections**
97-
98-
### **Mapping (`map`)**
53+
## ✨ Core Features
9954

100-
Applies a function to each element.
55+
### Smart Data Traversal
10156

102-
```php
103-
$mapped = $obj->shopList->map(fn($item) => strtoupper($item));
104-
print_r($mapped->toArray());
105-
```
106-
**Output:**
107-
```php
108-
['SOAP', 'TOOTHBRUSH', 'MILK', 'CHEESE', 'POTATOES', 'BEEF', 'FISH']
109-
```
110-
111-
### **Reducing (`reduce`)**
112-
113-
Combines values into a single result.
57+
Access deeply nested data without ever worrying about undefined keys.
11458

11559
```php
116-
$sum = $obj->feed->reduce(fn($carry, $item) => $carry + $item->salary->get(), 0);
117-
echo $sum;
118-
// Output: 60000
119-
```
120-
121-
### **Sorting (`reverse`, `shuffle`)**
122-
123-
```php
124-
echo $obj->shopList->reverse()->eq(0);
125-
// Output: fish
126-
```
60+
echo $obj->article->tagline->strToUpper();
61+
// Result: 'HELLO WORLD'
12762

128-
```php
129-
echo $obj->shopList->shuffle()->eq(0); // Random Output
130-
```
131-
132-
### **Chunking and Slicing (`chunk`, `slice`, `splice`)**
133-
134-
```php
135-
echo $obj->shopList->chunk(3)->count();
136-
// Output: 3
137-
```
138-
139-
```php
140-
echo $obj->shopList->slice(1, 2)->count();
141-
// Output: 2
142-
```
143-
144-
```php
145-
$spliced = $obj->shopList->splice(1, 2, ['replaced'])->toArray();
146-
print_r($spliced);
147-
```
148-
**Output:**
149-
```php
150-
['soap', 'replaced', 'potatoes', 'beef', 'fish']
63+
echo $obj->article->content->strExcerpt()->strUcFirst();
64+
// Result: 'Lorem ipsum dolor sit amet...'
15165
```
15266

15367
---
15468

155-
## **5. Modifying Collections**
156-
157-
### **Adding and Removing Items**
69+
### Built-In Data Transformation
15870

159-
```php
160-
echo $obj->shopList->push('barbie')->count();
161-
// Output: 8
162-
```
71+
Transform values directly using built-in helpers like:
16372

164-
```php
165-
echo $obj->shopList->pop($value)->count();
166-
echo $value;
167-
// Output: fish
168-
```
73+
#### Strings (`str`)
16974

17075
```php
171-
echo $obj->shopList->shift($value)->count();
172-
echo $value;
173-
// Output: soap
76+
echo $obj->title->strSlug();
77+
// Result: 'my-awesome-title'
17478
```
17579

176-
---
177-
178-
## **6. Advanced Traversal & Recursion**
179-
180-
### **Walking Through Nested Structures (`walk`, `walkRecursive`)**
80+
#### Numbers (`num`)
18181

18282
```php
183-
$value = "";
184-
$obj->feed->walkRecursive(function ($val) use (&$value) {
185-
$value .= strip_tags(str_replace(" ", "", $val));
186-
});
187-
echo $value;
188-
// Output: john1doe-1400001jane2doe-2200002
189-
```
190-
191-
### **Flattening Data (`flatten`, `flattenWithKeys`)**
83+
echo $obj->filesize->numToFilesize();
84+
// Result: '1.95 kb'
19285

193-
```php
194-
$flatten = $obj->feed->flatten()->map(fn($row) => $row->strToUpper())->toArray();
86+
echo $obj->price->numRound(2)->numToCurrency("USD");
87+
// Result: $1,999.99
19588
```
19689

197-
---
198-
199-
## **7. String, Number, and Date Handling**
200-
201-
### **String Manipulations**
90+
#### Dates (`clock`)
20291

20392
```php
204-
echo $obj->firstname->strStripTags()->strUcFirst();
205-
// Output: Daniel
206-
```
207-
208-
### **Number Formatting**
93+
echo $obj->created_at->clockFormat('d M, Y', 'sv_SE');
94+
// Result: '21 augusti 2025'
20995

210-
```php
211-
echo $obj->price->numToFilesize();
212-
// Output: 1.95 kb
96+
echo $obj->created_at->clockIsToday();
97+
// Result: true
21398
```
21499

215-
```php
216-
echo $obj->price->numRound(2)->numCurrency("SEK", 2);
217-
// Output: 1 999,99 kr
218-
```
219-
220-
### **Date Handling**
100+
#### HTML DOM Builder (`dom`)
221101

222102
```php
223-
echo $obj->date->clockFormat("y/m/d, H:i");
224-
// Output: 23/08/21, 14:35
103+
echo $obj->heading->domTag("h1.title");
104+
// Result: <h1 class="title">My Heading</h1>
225105
```
226106

107+
Or nest elements with ease:
108+
227109
```php
228-
\MaplePHP\DTO\Format\Clock::setDefaultLanguage('sv_SE');
229-
echo $obj->date->clockFormat('d M');
230-
// Output: 21 augusti
110+
echo $obj->title->domTag("h1.title")->domTag("header");
111+
// Result: <header><h1 class="title">Hello</h1></header>
231112
```
232113

233114
---
234115

235-
## **8. Array Utility Methods**
116+
### Built-In Collection Support
236117

237-
### **Merging and Replacing Arrays**
118+
Work with arrays of objects just as cleanly:
238119

239120
```php
240-
$merged = $obj->shopList->merge(['eggs', 'bread']);
241-
print_r($merged->toArray());
242-
```
243-
**Output:**
244-
```php
245-
['soap', 'toothbrush', 'milk', 'cheese', 'potatoes', 'beef', 'fish', 'eggs', 'bread']
121+
foreach ($obj->users->fetch() as $user) {
122+
echo $user->firstName->strUcFirst();
123+
}
246124
```
247125

248-
```php
249-
$replaced = $obj->shopList->replaceRecursive([0 => 'soap_bar']);
250-
print_r($replaced->toArray());
251-
```
252-
**Output:**
253-
```php
254-
['soap_bar', 'toothbrush', 'milk', 'cheese', 'potatoes', 'beef', 'fish']
255-
```
126+
---
256127

257-
### **Computing Differences (`diff`, `diffAssoc`, `diffKey`)**
128+
### Modify Data on the Fly
258129

259-
```php
260-
$diff = $obj->shopList->diff(['milk', 'cheese']);
261-
print_r($diff->toArray());
262-
```
263-
**Output:**
264-
```php
265-
['soap', 'toothbrush', 'potatoes', 'beef', 'fish']
266-
```
130+
Change values directly without verbose conditionals:
267131

268132
```php
269-
$diffAssoc = $obj->shopList->diffAssoc(['soap', 'toothbrush']);
270-
print_r($diffAssoc->toArray());
133+
$updated = $obj->shoppingList->replace([0 => 'Shampoo']);
134+
print_r($updated->toArray());
271135
```
272-
**Output:**
273-
```php
274-
['milk', 'cheese', 'potatoes', 'beef', 'fish']
275-
```
276-
277-
### **Extracting Keys (`keys`, `pluck`)**
278136

279-
```php
280-
print_r($obj->shopList->keys()->toArray());
281-
```
282-
**Output:**
283-
```php
284-
[0, 1, 2, 3, 4, 5, 6]
285-
```
137+
---
286138

287-
```php
288-
print_r($obj->feed->pluck('lastname')->toArray());
289-
```
290-
**Output:**
291-
```php
292-
['doe-1', 'doe-2']
293-
```
139+
Now go forth, write cleaner code, and let DTO handle the messy parts.

0 commit comments

Comments
 (0)