-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.html
1150 lines (1059 loc) · 57.5 KB
/
index.html
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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="en">
<head>
<title>Fomo documentation</title>
<!-- Meta -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="favicon.ico">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800'
rel='stylesheet' type='text/css'>
<!-- FontAwesome JS -->
<script defer src="assets/fontawesome/js/all.js"></script>
<!-- Global CSS -->
<link rel="stylesheet" href="assets/plugins/bootstrap/css/bootstrap.min.css">
<!-- Plugins CSS -->
<link rel="stylesheet" href="assets/plugins/elegant_font/css/style.css">
<link rel="stylesheet" href="assets/plugins/simplelightbox/simple-lightbox.min.css">
<!-- Theme CSS -->
<link id="theme-style" rel="stylesheet" href="assets/css/styles.css">
<link rel="stylesheet" href="assets/plugins/highlight/styles/base16/material-palenight.min.css">
</head>
<body class="body-green">
<div class="page-wrapper">
<div class="doc-wrapper">
<div class="container">
<div id="doc-header" class="doc-header text-center">
<img src="assets/images/logo.png" width="300px">
</div><!--//doc-header-->
<div class="doc-body row">
<div class="doc-content col-md-9 col-12 order-1">
<div class="content-inner">
<section class="doc-section">
<div></div></section><section class="doc-section"><h1 class="section-title" id="getting-started">Getting Started</h1><div class="section-block">
</div></section><section class="doc-section"><h2 class="section-title" id="introduction">Introduction</h2><div class="section-block">
<p>Fomo is a web application framework based.</p>
<p>We tried to implement Fomo in the simplest possible way so that anyone can use it.</p>
<p>Fomo supports the following:</p>
<ul>
<li>Simple, fast routing engine.</li>
<li>Processing work in the background.</li>
<li>Queued job processing.</li>
<li>And more...</li>
</ul>
<p>Fomo is very fast, simple and for use in large scale projects.</p>
</div></section><section class="doc-section"><h2 class="section-title" id="why-fomo">Why Fomo?</h2><div class="section-block">
<p>Here's 3 reason why you should use Fomo:</p>
<ul>
<li>Fomo is very simple (less to learn and train others on).</li>
<li>Fomo is very fast (uses fewer resources to do the same thing).</li>
<li>Fomo is another tool that developers can use to solve their complex problems in a simple way.</li>
</ul>
</div></section><section class="doc-section"><h2 class="section-title" id="first-fomo-project">First Fomo Project</h2><div class="section-block">
<h4>Tip</h4>
<p>We have not tested Fomo on Windows. It may work just fine, but you may encounter problems installing and running Fomo. If there is a problem, send us the error message <a href="https://github.com/Fomo-framework/Fomo/issues">in a Github issue</a>.</p>
<p>Before creating your first Fomo project, you should ensure that your local machine has PHP, Composer, Swoole, Posix, Pcntl, and Redis installed.</p>
<p>After you have installed those dependencies, you may create a new Fomo project via the Composer create-project command:</p>
<pre><code>composer create-project Fomo/Fomo example</code></pre>
<p>After creating the project, start the Fomo development server using Mr. Engineer:</p>
<pre><code>cd example
php engineer server:start</code></pre>
<p>Once you have started the development server via the engineer command, your application will be accessible in your web browser at <a href="http://localhost:9000">http://localhost:9000</a>.</p>
</div></section><section class="doc-section"><h2 class="section-title" id="mr-engineer">Mr. Engineer</h2><div class="section-block">
<p>In Fomo, the boss is Mr. Engineer. In a funny, but serious way all orders are issued by Mr. Engineer to help keep your projects architecture consistent.</p>
<p>Commands like:</p>
<ul>
<li>Start the HTTP server</li>
<li>Start the queue server</li>
<li>Start the scheduling server</li>
<li>Making controller, resource, middleware, service, job, task, etc...</li>
<li>Run tests</li>
<li>And more...</li>
</ul>
<p>To see the commands that Mr. Engineer can issue You can run the following command</p>
<pre><code>php engineer list</code></pre>
</div></section><section class="doc-section"><h1 class="section-title" id="the-basics">The Basics</h1><div class="section-block">
</div></section><section class="doc-section"><h2 class="section-title" id="routing">Routing</h2><div class="section-block">
<p>tip: Routes are registered in routes/api.php</p>
<h3>Basic Route</h3>
<p>the most basic Fomo routes accept a URI and a callback, providing a very simple and expressive method of defining routes and behavior without complicated routing configuration files:</p>
<pre><code class="language-php"><?php
namespace App\Controllers;
use Fomo\Request\Request;
use Fomo\Response\Response;
class TestController extends Controller
{
public function getUsers(Request $request): Response
{
return response()->json([
'message' => 'OK'
]);
}
}</code></pre>
<p>tip: Note in getUsers method, if there is no mandatory parameter, the first entry can be deleted</p>
<pre><code class="language-php"><?php
/** @var Fomo\Router\Router $router */
use App\Controllers\TestController;
$router->get('/users' , [TestController::class , 'getUsers']);</code></pre>
<h3>Available Router Methods</h3>
<pre><code class="language-php">$router->get($uri , $callback);
$router->post($uri , $callback);
$router->put($uri , $callback);
$router->patch($uri , $callback);
$router->delete($uri , $callback);
$router->head($uri , $callback);
$router->any($uri , $callback);</code></pre>
<h3>Route Parameters</h3>
<h4>tip</h4>
<p>If you use parameters, note that it must be the first callback input of the Request class. And the parameters must be received exactly in the same order as specified in the uri (we will explain more later)</p>
<p>Sometimes you will need to capture segments of the URI within your route. For example, you may need to capture a user's ID from the URL. You may do so by defining route parameters:</p>
<pre><code class="language-php"><?php
namespace App\Controllers;
use Fomo\Request\Request;
use Fomo\Response\Response;
class TestController extends Controller
{
public function getUser(Request $request, int $id): Response
{
return response()->json([
'userId' => $id
]);
}
}</code></pre>
<pre><code class="language-php"><?php
/** @var Fomo\Router\Router $router */
use App\Controllers\TestController;
$router->get('/users/{id}' , [TestController::class , 'getUser']);</code></pre>
<h3>Group</h3>
<p>You can add a middleware or a prefix to several paths or delete a middleware for several paths</p>
<pre><code class="language-php">$router->group([
'middleware' => ['first' , 'second'] , // 'middleware' => 'first'
'prefix' => 'admin' ,
'withoutMiddleware' => 'first' ,
], function () use ($router) {
//
}
);</code></pre>
<h3>Middleware</h3>
<p>To assign middleware to all routes within a group, you may use the middleware method before defining the group. Middleware are executed in the order they are listed in the array:</p>
<pre><code class="language-php">$router->middleware(['first', 'second'])->group([] , function () use ($router) {
//
});</code></pre>
<h3>Without Middleware</h3>
<p>If the desired middleware exists in the path, it will be deleted</p>
<pre><code class="language-php">$router->withoutMiddleware('first')->get($uri, $callback);</code></pre>
<h3>Prefix</h3>
<p>The prefix method may be used to prefix each route in the group with a given URI. For example, you may want to prefix all route URIs within the group with admin:</p>
<pre><code class="language-php">$router->prefix('admin')->group([] , function () use ($router) {
$router->get('users' , $callback); // Matches The "/admin/users" URL
});</code></pre>
</div></section><section class="doc-section"><h2 class="section-title" id="controller">Controller</h2><div class="section-block">
<h3>Make A controller</h3>
<p>If you want to create a new controller, follow the command below</p>
<pre><code>php engineer build:controller ControllerName</code></pre>
<h3>Basic Controller</h3>
<p>Let's take a look at an example of a basic controller. Note that the controller extends the base controller class included with Fomo: App\Controllers\Controller:</p>
<pre><code class="language-php">namespace App\Controllers;
use Fomo\Request\Request;
use Fomo\Response\Response;
class TestController extends Controller
{
public function store(Request $request): Response
{
// insert data
return response()->asNoContent();
}
}</code></pre>
</div></section><section class="doc-section"><h2 class="section-title" id="middleware">Middleware</h2><div class="section-block">
<h3>Make A Middleware</h3>
<p>If you want to create a new middleware, follow the command below</p>
<pre><code class="language-php">php engineer build:middleware MiddlewareName</code></pre>
<h3>Basic Middleware</h3>
<p>Let's take a look at an example of a basic controller. Note that the output of the middleware should be 'true' if all operations are performed correctly, and otherwise it should be a Response class.</p>
<pre><code class="language-php">namespace App\Middlewares;
use Fomo\Request\Request;
use Fomo\Response\Response;
class TestMiddleware
{
public function handle(Request $request): bool|Response
{
if ($request->get('token') == 'my-secret-token'){
return true;
}
return response()->json([
'message' => 'ERROR'
]);
}
}</code></pre>
<h3>Assigning Middleware To Routes</h3>
<p>If you want to assign the middleware to specific paths, you can use the following methods</p>
<pre><code class="language-php">// Example 1
$router->middleware('first')->get($uri, $callback);
// Example 2
$router->middleware(FirstMiddleware::class)->get($uri, $callback);
// Example 3
$router->middleware(['first' , SecondMiddleware::class])->get($uri, $callback);
// Example 4
$router->group(['middleware' => 'first'] , function () use ($router){
//
});</code></pre>
<h3>Excluding Middleware</h3>
<p>When assigning middleware to a group of routes, you may occasionally need to prevent the middleware from being applied to an individual route within the group. You may accomplish this using the withoutMiddleware method:</p>
<pre><code class="language-php">// Example 1
$router->withoutMiddleware('first')->get($uri, $callback);
// Example 2
$router->withoutMiddleware(FirstMiddleware::class)->get($uri, $callback);
// Example 3
$router->withoutMiddleware(['first' , SecondMiddleware::class])->get($uri, $callback);
// Example 4
$router->group(['withoutMiddleware' => 'first'] , function () use ($router){
//
});</code></pre>
</div></section><section class="doc-section"><h2 class="section-title" id="request">Request</h2><div class="section-block">
<p>Fomo's Fomo\Request\Request class provides an object-oriented way to interact with the current HTTP request being handled by your application as well as retrieve the input that were submitted with the request.</p>
<h3>Accessing The Request</h3>
<p>To obtain an instance of the current HTTP request via dependency injection, you should type-hint the Fomo\Request\Request class on your route closure or controller method.</p>
<pre><code class="language-php">namespace App\Controllers;
use Fomo\Request\Request;
use Fomo\Response\Response;
class UserController extends Controller
{
public function store(Request $request): Response
{
$name = $request->input('name');
//
}
}</code></pre>
<h3>Retrieving The Request Path</h3>
<p>The path method returns the request's path information. So, if the incoming request is targeted at <a href="http://example.com/foo/bar">http://example.com/foo/bar</a>, the path method will return foo/bar:</p>
<pre><code class="language-php">$uri = $request->path();</code></pre>
<h3>Retrieving The Request URL</h3>
<p>To retrieve the full URL for the incoming request you may use the url or fullUrl methods. The url method will return the URL without the query string, while the fullUrl method includes the query string:</p>
<pre><code class="language-php">$url = $request->url();
$urlWithQueryString = $request->fullUrl();</code></pre>
<h3>Retrieving The Request Method</h3>
<p>The method method will return the HTTP verb for the request.</p>
<pre><code class="language-php">$method = $request->method();</code></pre>
<h3>Headers</h3>
<p>You may retrieve a request header from the Fomo\Request\Request instance using the header method. If the header is not present on the request, null will be returned. However, the header method accepts an optional second argument that will be returned if the header is not present on the request:</p>
<pre><code class="language-php">$value = $request->header('X-Header-Name', 'default');</code></pre>
<h3>Retrieving Get Input Values</h3>
<p>You can access data of type GET using the following method</p>
<pre><code class="language-php">$name = $request->get('name', 'default');</code></pre>
<p>When working with forms that contain array inputs, use "dot" notation to access the arrays. (Note that to activate this section, you must ENABLE the request index in the config/server.php file in the advanceMode presentation)</p>
<pre><code class="language-php">$name = $request->get('products.0.name');
$names = $request->get('products.*.name');</code></pre>
<h3>Retrieving POST Input Values</h3>
<p>You can access data of type POST using the following method</p>
<pre><code class="language-php">$name = $request->post('name', 'default');</code></pre>
<p>When working with forms that contain array inputs, use "dot" notation to access the arrays. (Note that to activate this section, you must ENABLE the request index in the config/server.php file in the advanceMode presentation)</p>
<pre><code class="language-php">$name = $request->post('products.0.name');
$names = $request->post('products.*.name');</code></pre>
<h3>Retrieving Protocol Version</h3>
<p>You can access the protocol version using the following method</p>
<pre><code class="language-php">$protocolVersion = $request->protocolVersion();</code></pre>
<h3>Retrieving uri</h3>
<p>You can access the uri using the following method</p>
<pre><code class="language-php">$uri = $request->uri();</code></pre>
<h3>Retrieving queryString</h3>
<p>You can access the queryString using the following method</p>
<pre><code class="language-php">$queryString = $request->queryString();</code></pre>
<h3>Retrieving variable</h3>
<p>You can access the path input parameters using the following method</p>
<pre><code class="language-php">$queryString = $request->variable('id');</code></pre>
<h3>IP Address</h3>
<p>The ip method may be used to retrieve the IP address of the client that made the request to your application:</p>
<pre><code class="language-php">// example 1
$ipAddress = $request->remoteIp();
// example 2
$ipAddress = $request->ip();</code></pre>
<h3>Retrieving All Input Data</h3>
<p>You may retrieve all of the incoming request's input data as an array using the all method. This method may be used regardless of whether the incoming request is from an HTML form or is an XHR request:</p>
<pre><code class="language-php">$input = $request->all();</code></pre>
<h3>Retrieving An Input Value</h3>
<p>Using a few simple methods, you may access all of the user input from your Fomo\Request\Request instance without worrying about which HTTP verb was used for the request. Regardless of the HTTP verb, the input method may be used to retrieve user input:</p>
<pre><code class="language-php">$name = $request->input('name' , 'default');</code></pre>
<p>When working with forms that contain array inputs, use "dot" notation to access the arrays. (Note that to activate this section, you must ENABLE the request index in the config/server.php file in the advanceMode presentation)</p>
<pre><code class="language-php">$name = $request->input('products.0.name');
$names = $request->input('products.*.name');</code></pre>
<h3>Retrieving A Portion Of The Input Data</h3>
<p>If you need to retrieve a subset of the input data, you may use the only and except methods. Both of these methods accept a single array or a dynamic list of arguments:</p>
<pre><code class="language-php">$input = $request->only(['username', 'password']);
$input = $request->only('username', 'password');
$input = $request->except(['credit_card']);
$input = $request->except('credit_card');</code></pre>
</div></section><section class="doc-section"><h2 class="section-title" id="response">Response</h2><div class="section-block">
<p>Fomo\Response\Response class Fomo An object-oriented way to HTTP Response</p>
<h3>response</h3>
<p>Using the following method, you can create your response in any way you want</p>
<pre><code class="language-php">namespace App\Controllers;
use Fomo\Request\Request;
use Fomo\Response\Response;
class UserController extends Controller
{
public function store(Request $request): Response
{
return response(
'message' ,
200 ,
[
'Connection' => 'keep-alive' // default
]
);
}
}</code></pre>
<h3>withHeader</h3>
<p>Add a header to the response</p>
<pre><code class="language-php">return response()->withHeader('name' , 'value');</code></pre>
<h3>withHeaders</h3>
<p>Add some headers to the response</p>
<pre><code class="language-php">return response()->withHeaders([
'first' , 'value' ,
'second' => 'value'
]);</code></pre>
<h3>withStatus</h3>
<p>Set response status</p>
<pre><code class="language-php">return response()->withStatus(400);</code></pre>
<h3>withBody</h3>
<p>Set response message</p>
<pre><code class="language-php">return response()->withBody('response message');</code></pre>
<h3>json</h3>
<p>The json method will automatically set the Content-Type header to application/json, as well as convert the given array to JSON using the json_encode PHP function:</p>
<pre><code class="language-php">return response()->json([
'name' => 'Abigail',
'state' => 'CA',
]);</code></pre>
<h3>noContent</h3>
<p>The noContent method will automatically set the Content-Type header to text/html; charset=utf-8, Content-Length header to 0 and also sets the value of the message equal to ''</p>
<pre><code class="language-php">return response()->noContent();</code></pre>
<h3>asHtml</h3>
<p>The html method will automatically set the Content-Type header to text/html; charset=utf-8, Content-Length header to strlen($html)</p>
<pre><code class="language-php">return response()->html($html , 200);</code></pre>
</div></section><section class="doc-section"><h2 class="section-title" id="validation">Validation</h2><div class="section-block">
<p>Fomo includes a wide variety of convenient validation rules that you may apply to data, even providing the ability to validate if values are unique in a given database table. We'll cover each of these validation rules in detail so that you are familiar with all of Fomo's validation features.</p>
<h3>Validation Quickstart</h3>
<p>Consider, we want to validate people's information:</p>
<h4>routes/api.php</h4>
<pre><code class="language-php">/** @var Fomo\Router\Router $router */
$router->post('users' , [\App\Controllers\UserController::class , 'store']);</code></pre>
<h4>app/Controllers/UserController.php</h4>
<pre><code class="language-php">namespace App\Controllers;
use Fomo\Request\Request;
use Fomo\Response\Response;
use Fomo\Validation\Validation;
class UserController extends Controller
{
public function store(Request $request): Response
{
$validate = new Validation($request->post() , [
'name.firstName' => 'required|string|max:255|min:10',
'name.lastName' => 'required|string|max:255|min:10',
'age' => 'required|date:Y-m-d',
]);
if ($validate->hasError()){
return response()->json([
'errors' => $validate->getErrors()
] , 422);
}
return response()->json([
'message' => 'OK'
]);
}
}</code></pre>
<h3>hasError</h3>
<p>The following method determines whether the information sent has errors or not</p>
<pre><code class="language-php">if ($validate->hasError()){
//
}</code></pre>
<h3>hasMessage</h3>
<p>The following method determines whether the information sent has errors or not</p>
<pre><code class="language-php">if ($validate->hasMessage()){
//
}</code></pre>
<h3>getMessages</h3>
<p>The following method returns an array of all error messages if there is an error, otherwise it returns an empty array.</p>
<pre><code class="language-php">if ($validate->hasError()){
return response()->json([
'errorMessages' => $validate->getErrors()
] , 422);
}</code></pre>
<h3>firstMessage</h3>
<p>If there is an error, the following method returns only the first error message</p>
<pre><code class="language-php">if ($validate->hasError()){
return response()->json([
'firstErrorMessage' => $validate->firstMessage()
] , 422);
}</code></pre>
<h3>getErrors</h3>
<p>If there is an error, the following method returns the complete information of that error (including the desired field of the error message only for each field and...)</p>
<pre><code class="language-php">if ($validate->hasError()){
return response()->json([
'errors' => $validate->getErrors()
] , 422);
}</code></pre>
<h3>firstErrors</h3>
<p>If there is an error, the following method returns the complete information of the first error (including the desired field of the error message only for each field and...)</p>
<pre><code class="language-php">if ($validate->hasError()){
return response()->json([
'firstError' => $validate->firstError()
] , 422);
}</code></pre>
<h3>Available Validation Rules</h3>
<h6>after:field</h6>
<p>The field to be verified must have a value greater than the specified field</p>
<h6>before:field</h6>
<p>The field to be verified must have a value less than the specified field</p>
<h6>required</h6>
<p>The desired field must have a value and cannot be without a value</p>
<h6>string</h6>
<p>The desired field must be of string type</p>
<h6>integer</h6>
<p>The desired field must be of integer type</p>
<h6>boolean</h6>
<p>The desired field must be of boolean type</p>
<h6>array</h6>
<p>The desired field must be of array type</p>
<h6>email</h6>
<p>The field under validation must be formatted as an email address.</p>
<h6>regex:pattern</h6>
<p>The field under validation must match the given regular expression.</p>
<h6>notRegex:pattern</h6>
<p>The field under validation must not match the given regular expression.</p>
<h6>max:value</h6>
<p>The field under validation must be less than or equal to a maximum value. Strings, numerics, arrays, and files are evaluated in the same fashion as the size rule.</p>
<h6>min:value</h6>
<p>The field under validation must have a minimum value. Strings, numerics, arrays, and files are evaluated in the same fashion as the size rule.</p>
<h6>size:value</h6>
<p>The field under validation must have a size matching the given value. For string data, value corresponds to the number of characters. For numeric data, value corresponds to a given integer value (the attribute must also have the numeric or integer rule). For an array, size corresponds to the count of the array.</p>
<h6>date:format</h6>
<p>The field under validation must be a valid, date according to the Carbon.</p>
<h6>in:foo,bar,...</h6>
<p>The field under validation must be included in the given list of values.</p>
<h6>exists:table,column</h6>
<p>The field under validation must exist in a given database table.</p>
<h6>unique:table,column</h6>
<p>The field under validation must not exist within the given database table.</p>
</div></section><section class="doc-section"><h2 class="section-title" id="log">Log</h2><div class="section-block">
<p>To help you learn more about what's happening within your application, Fomo provides robust logging services that allow you to log messages to files, the system error log to notify your entire team.</p>
<h3>channel</h3>
<p>Set log file name (default: Fomo)</p>
<pre><code class="language-php">use Fomo\Log\Log;
Log::channel('security')->emergency('The system is down!');</code></pre>
<h3>Writing Log Messages</h3>
<p>You may write information to the logs using the Log facade. As previously mentioned, the logger provides the eight logging levels defined in the RFC 5424 specification: emergency, alert, critical, error, warning, notice, info and debug:</p>
<pre><code class="language-php">use Fomo\Log\Log;
Log::info($message, $content);
Log::alert($message, $content);
Log::critical($message, $content);
Log::debug($message, $content);
Log::emergency($message, $content);
Log::error($message, $content);
Log::log($message, $content);
Log::notice($message, $content);
Log::warning($message, $content);</code></pre>
</div></section><section class="doc-section"><h1 class="section-title" id="a-little-deeper">A Little Deeper</h1><div class="section-block">
</div></section><section class="doc-section"><h2 class="section-title" id="cache">Cache</h2><div class="section-block">
<p>Some of the data retrieval or processing tasks performed by your application could be CPU intensive or take several seconds to complete. When this is the case, it is common to cache the retrieved data for a time so it can be retrieved quickly on subsequent requests for the same data. The cached data is usually stored in a very fast data store such as Redis.</p>
<h3>Cache Usage</h3>
<h6>get instance of Cache</h6>
<p>You can use the following method to get a cache sample</p>
<pre><code class="language-php">use Fomo\Cache\Cache;
$cache = new Cache();</code></pre>
<h6>Retrieving Items From The Cache</h6>
<p>The Cache class's get method is used to retrieve items from the cache. If the item does not exist in the cache, null will be returned. If you wish, you may pass a second argument to the get method specifying the default value you wish to be returned if the item doesn't exist:</p>
<pre><code class="language-php">$value = $cache->get('key');</code></pre>
<p>You may even pass a closure as the default value. The result of the closure will be returned if the specified item does not exist in the cache. Passing a closure allows you to defer the retrieval of default values from a database or other external service:</p>
<pre><code class="language-php">$value = $cache->get('key' , function () {
return DB::table(/* ... */)->get();
});</code></pre>
<h6>Checking For Item Existence</h6>
<p>The has method may be used to determine if an item exists in the cache:</p>
<pre><code class="language-php">if ($cache->has('key')) {
//
}</code></pre>
<h6>Retrieve & Store</h6>
<p>Sometimes you may wish to retrieve an item from the cache, but also store a default value if the requested item doesn't exist. For example, you may wish to retrieve all users from the cache or, if they don't exist, retrieve them from the database and add them to the cache. You may do this using the remember method:</p>
<pre><code class="language-php">$value = $cache->remember('users', $seconds, function () {
return DB::table('users')->get();
});</code></pre>
<p>If the item does not exist in the cache, the closure passed to the remember method will be executed and its result will be placed in the cache.</p>
<p>You may use the rememberForever method to retrieve an item from the cache or store it forever if it does not exist:</p>
<pre><code class="language-php">$value = $cache->rememberForever('users', $seconds, function () {
return DB::table('users')->get();
});</code></pre>
<h6>Retrieve & Delete</h6>
<p>If you need to retrieve an item from the cache and then delete the item, you may use the pull method. Like the get method, null will be returned if the item does not exist in the cache:</p>
<pre><code class="language-php">$value = $cache->pull('key');</code></pre>
<h6>Storing Items In The Cache</h6>
<p>You may use the put method on the Cache class to store items in the cache:</p>
<pre><code class="language-php">$cache->put('key' , 'value' , $seconds = 10);</code></pre>
<p>If the storage time is not passed to the put method, the item will be stored indefinitely:</p>
<pre><code class="language-php">$cache->put('key' , 'value');</code></pre>
</div></section><section class="doc-section"><h2 class="section-title" id="helpers">Helpers</h2><div class="section-block">
<p>Fomo includes a variety of global helper PHP functions. Many of these functions are used by the framework itself; however, you are free to use them in your own applications if you find them convenient.</p>
<h3>Application Helpers</h3>
<h4>basePath(string $path = null)</h4>
<p>The basePath function returns the fully qualified path to your application's root directory. You may also use the basePath function to generate a fully qualified path to a given file relative to the project root directory:</p>
<pre><code class="language-php">// pulls from PROJECT_PATH
// PROJECT_PATH is defined in `engineer` as `realpath('./');`
// Ex: /home/user/projects/my-project/ as directory
$path = basePath();
// Returns: /home/user/projects/my-project/
// Note: There is a trailing slash
$path = basePath('vendor/bin');
// Returns: /home/user/projects/my-project/vendor/bin
// Note: If you don't define a trailing slash, there won't be one!</code></pre>
<h4>appPath(string $path = null)</h4>
<p>The appPath function returns the fully qualified path to your application's app directory. You may also use the appPath function to generate a fully qualified path to a file relative to the application directory:</p>
<pre><code class="language-php">// Ex: /home/user/projects/my-project/ as directory
$path = appPath();
// Returns: /home/user/projects/my-project/app/
$path = appPath('Controllers/Controller.php');
// Returns: /home/user/projects/my-project/app/Controllers/Controller.php</code></pre>
<h4>configPath(string $path = null)</h4>
<p>The configPath function returns the fully qualified path to your application's config directory. You may also use the configPath function to generate a fully qualified path to a given file within the application's configuration directory:</p>
<pre><code class="language-php">// Ex: /home/user/projects/my-project/ as directory
$path = configPath();
// Returns: /home/user/projects/my-project/config/
$path = configPath('app.php');
// Returns: /home/user/projects/my-project/config/app.php</code></pre>
<h4>databasePath(string $path = null)</h4>
<p>The databasePath function returns the fully qualified path to your application's database directory. You may also use the databasePath function to generate a fully qualified path to a given file within the database directory:</p>
<pre><code class="language-php">// Ex: /home/user/projects/my-project/ as directory
$path = databasePath();
// Returns: /home/user/projects/my-project/database/
$path = databasePath('Factory.php');
// Returns: /home/user/projects/my-project/database/Factory.php</code></pre>
<h4>languagePath(string $path = null)</h4>
<p>The languagePath function returns the fully qualified path to your application's language directory. You may also use the languagePath function to generate a fully qualified path to a given file within the directory:</p>
<pre><code class="language-php">// Ex: /home/user/projects/my-project/ as directory
$path = languagePath();
// Returns: /home/user/projects/my-project/language/
$path = languagePath('validation/en');
// Returns: /home/user/projects/my-project/language/validation/en</code></pre>
<h4>storagePath(string $path = null)</h4>
<p>The storagePath function returns the fully qualified path to your application's storage directory. You may also use the storagePath function to generate a fully qualified path to a given file within the directory:</p>
<pre><code class="language-php">// Ex: /home/user/projects/my-project/ as directory
$path = storagePath();
// Returns: /home/user/projects/my-project/storage/
$path = storagePath('logs/Fomo.log');
// Returns: /home/user/projects/my-project/storage/logs/Fomo.log</code></pre>
<h4>config(string $key, $default = null)</h4>
<p>The config function gets the value of a configuration variable. The configuration values may be accessed using "dot" syntax, which includes the name of the file and the option you wish to access. A default value may be specified and is returned if the configuration option does not exist:</p>
<pre><code class="language-php">// from app/config/app.php
return [
'timezone' => 'UTC',
];
// When pulling the value within your application
$value = config('app.timezone');
// Returns: UTC
$default = 'GMT';
$value = config('app.timezone', $default);
// Returns: UTC, but if the value is not set, it will return GMT</code></pre>
<h4>request()</h4>
<p>The request function returns an instance of the current request from the request factory:</p>
<pre><code class="language-php">// Full request object
$request = request();
// URL Path
$path = request()->path();
// IP
$ip = request()->ip();
// Get a URL parameter
// Ex: example.com/users/1?name=John
$name = request()->get('name');
// Returns; John</code></pre>
<h4>response()</h4>
<p>The response function creates a response instance or obtains an instance of the response factory:</p>
<pre><code class="language-php">$html = '<html><body><h1>Hello, World!</h1></body></html>';
$statusCode = 200;
// Automatically sets the Content-Type header to text/html; charset=utf-8
return response()->html($html, $statusCode);
// Automatically sets the Content-Type header to application/json
return response()->json(['foo' => 'bar'], 200);
// or with custom headers
return response()
->withHeaders(['X-Header' => 'Value'])
->json(['foo' => 'bar'], 200);</code></pre>
<h4>auth()</h4>
<p>The auth function returns an authenticator instance. You may use it as an alternative to the <code>Auth</code> class:</p>
<pre><code class="language-php">$user = auth()->user();</code></pre>
<h4>elasticsearch()</h4>
<p>The elasticsearch function returns an elasticsearch instance. You may use it as a shortcut to the Elasticsearch class:</p>
<pre><code class="language-php">$searchResults = elasticsearch()->msearch(/* set your query */);</code></pre>
<h4>redis()</h4>
<p>The redis function returns an redis instance. You may use it as an alternative to the Redis class:</p>
<pre><code class="language-php">$myCachedRedisValue = redis()->get(/*get your key */);</code></pre>
<h4>mail()</h4>
<p>The mail function returns an mail instance. You may use it as an alternative to the Mail class:</p>
<pre><code class="language-php">mail()->body(/*set your body */)->send();</code></pre>
<h4>cache()</h4>
<p>The cache function returns a cache instance. You may use it as an alternative to the Cache class:</p>
<pre><code class="language-php">$myCachedValue = cache()->get(/*get your key */);</code></pre>
<h4>validation()</h4>
<p>The validation function returns a validation instance. You may use it as an alternative to the Validation class:</p>
<pre><code class="language-php">$hasError = validation($myValidationData, $myRules)->hasError();</code></pre>
<h4>env(mixed $key, mixed $default = null)</h4>
<p>The env function retrieves the value of an environment variable or returns a default value:</p>
<pre><code class="language-php">$env = env('APP_ENV');
$env = env('APP_ENV', 'production');</code></pre>
<h3>Swoole Helpers</h3>
<h4>cpuCount()</h4>
<p>The cpuCount function returns the number of CPU cores available on the server:</p>
<pre><code class="language-php">$cores = cpuCount();</code></pre>
<h4>getMasterProcessId()</h4>
<p>The getMasterProcessId function returns the master process ID:</p>
<pre><code class="language-php">$masterId = getMasterProcessId();</code></pre>
<h4>getWorkerProcessIds()</h4>
<p>The getWorkerProcessIds function returns an array of worker process IDs:</p>
<pre><code class="language-php">$workerIds = getWorkerProcessIds();</code></pre>
<h4>getManagerProcessId()</h4>
<p>The getManagerProcessId function returns the manager process ID:</p>
<pre><code class="language-php">$managerId = getManagerProcessId();</code></pre>
<h4>getWatcherProcessId()</h4>
<p>The getWatcherProcessId function returns the watcher process ID:</p>
<pre><code class="language-php">$watcherId = getWatcherProcessId();</code></pre>
<h4>getFactoryProcessId()</h4>
<p>The getFactoryProcessId function returns the factory process ID:</p>
<pre><code class="language-php">$factoryId = getFactoryProcessId();</code></pre>
<h4>getQueueProcessId()</h4>
<p>The getQueueProcessId function returns the queue process ID:</p>
<pre><code class="language-php">$queueId = getQueueProcessId();</code></pre>
<h4>getSchedulingProcessId()</h4>
<p>The getSchedulingProcessId function returns the scheduling process ID:</p>
<pre><code class="language-php">$schedulingId = getSchedulingProcessId();</code></pre>
<h4>httpServerIsRunning()</h4>
<p>The httpServerIsRunning function returns true if the HTTP server is running:</p>
<pre><code class="language-php">$is_running = httpServerIsRunning();</code></pre>
<h4>queueServerIsRunning()</h4>
<p>The queueServerIsRunning function returns true if the queue server is running:</p>
<pre><code class="language-php">$is_running = queueServerIsRunning();</code></pre>
<h4>schedulingServerIsRunning()</h4>
<p>The schedulingServerIsRunning function returns true if the scheduling server is running:</p>
<pre><code class="language-php">$is_running = schedulingServerIsRunning();</code></pre>
</div></section><section class="doc-section"><h1 class="section-title" id="server">Server</h1><div class="section-block">
</div></section><section class="doc-section"><h2 class="section-title" id="http-client">HTTP Client</h2><div class="section-block">
<p>Fomo provides an expressive, minimal API around the Guzzle HTTP client, allowing you to quickly make outgoing HTTP requests to communicate with other web applications. Fomo's wrapper around Guzzle is focused on its most common use cases and a wonderful developer experience.</p>
<h3>Making Requests</h3>
<p>To make requests, you may use the head, get, post, headput, patch, and delete methods provided by the Http facade. First, let's examine how to make a basic GET request to another URL:</p>
<pre><code class="language-php">use Fomo\Http\Http;
$http = new Http();
$response = $http->get('http://example.com');</code></pre>
<p>The get method returns an instance of Fomo\Http\Response, which provides a variety of methods that may be used to inspect the response:</p>
<pre><code class="language-php">$response->body() : string;
$response->json($key = null) : array|mixed;
$response->object() : object;
$response->status() : int;
$response->ok() : bool;
$response->successful() : bool;
$response->redirect(): bool;
$response->failed() : bool;
$response->serverError() : bool;
$response->clientError() : bool;
$response->header($header) : string;
$response->headers() : array;</code></pre>
<h3>Request Data</h3>
<p>Of course, it is common when making POST, PUT, and PATCH requests to send additional data with your request, so these methods accept an array of data as their second argument. By default, data will be sent using the application/json content type:</p>
<pre><code class="language-php">$response = $http->post('http://example.com', [
'foo' => 'bar'
]);</code></pre>
<h3>GET Request Query Parameters</h3>
<p>When making GET requests, you may either append a query string to the URL directly or pass an array of key / value pairs as the second argument to the get method:</p>
<pre><code class="language-php">$response = $http->get('http://example.com', [
'foo' => 'bar'
]);</code></pre>
<h3>Sending Form URL Encoded Requests</h3>
<p>If you would like to send data using the application/x-www-form-urlencoded content type, you should call the asForm method before making your request:</p>
<pre><code class="language-php">$response = $http->asForm()->post('http://example.com', [
'foo' => 'bar'
]);</code></pre>
<h3>Sending A Raw Request Body</h3>
<p>You may use the withBody method if you would like to provide a raw request body when making a request. The content type may be provided via the method's second argument:</p>
<pre><code class="language-php">$response = $http->withBody(
base64_encode($photo), 'image/jpeg'
)->post('http://example.com');</code></pre>
<h3>Multi-Part Requests</h3>
<p>If you would like to send files as multi-part requests, you should call the attach method before making your request. This method accepts the name of the file and its contents. If needed, you may provide a third argument which will be considered the file's filename:</p>
<pre><code class="language-php">$response = $http->attach(
'attachment', file_get_contents('photo.jpg'), 'photo.jpg'
)->post('http://example.com');</code></pre>
<p>Instead of passing the raw contents of a file, you may pass a stream resource:</p>
<pre><code class="language-php">$photo = fopen('photo.jpg', 'r');
$response = $http->attach(
'attachment', $photo, 'photo.jpg'
)->post('http://example.com');</code></pre>
<h3>Headers</h3>
<p>Headers may be added to requests using the withHeaders method. This withHeaders method accepts an array of key / value pairs:</p>
<pre><code class="language-php">$response = $http->withHeaders([
'X-First' => 'foo',
'X-Second' => 'bar'
])->post('http://example.com', [
'foo' => 'bar',
]);</code></pre>
<h3>Error Handling</h3>
<p>Unlike Guzzle's default behavior, Fomo's HTTP client wrapper does not throw exceptions on client or server errors (400 and 500 level responses from servers). You may determine if one of these errors was returned using the isSuccessfulsuccessful, isClientError, or isServerError methods:</p>
<pre><code class="language-php">// Determine if the status code is >= 200 and < 300...
$response->isSuccessful();
// Determine if the status code is >= 400...
$response->isFailed();
// Determine if the response has a 400 level status code...
$response->isClientError();
// Determine if the response has a 500 level status code...
$response->isServerError();
// Immediately execute the given callback if there was a client or server error...
$response->onError(callable $callback);
</code></pre>
</div></section><section class="doc-section"><h2 class="section-title" id="http-server">HTTP Server</h2><div class="section-block">
<p>An HTTP server is a computer (software) program (or even a software component included in an other program) that plays the role of a server in a client–server model by implementing the server part of the HTTP and/or HTTPS network protocol(s). An HTTP server waits for the incoming client requests (sent by user agents like browsers, web crawlers, etc.) and for each request it answers by replying with requested information, including the sending of the requested web resource, or with an HTTP error message.</p>
<h3>start command</h3>
<p>You can use the following command to start the server</p>
<pre><code class="language-bash">php engineer server:start</code></pre>
<p>With the options --watch or -w, you can give this command to the server, so that if there are changes in the files, the server will automatically reload in real time.</p>
<pre><code class="language-bash">php engineer server:start -w
# or
php engineer server:start --watch</code></pre>
<p>With the options --daemonize or -d, you can give this command to the server, so that the server runs in the background</p>
<pre><code class="language-bash">php engineer server:start -d
//or
php engineer server:start --daemonize</code></pre>
<h3>reload command</h3>
<p>You can reload the server with the following command</p>
<pre><code class="language-bash">php engineer server:reload</code></pre>
<h3>status command</h3>
<p>You can check the status of all processes with the following command</p>
<pre><code class="language-bash">php engineer server:status</code></pre>
<h3>stop command</h3>
<p>You can stop the server with the following command</p>
<pre><code class="language-bash">php engineer server:stop</code></pre>
</div></section><section class="doc-section"><h2 class="section-title" id="queue-server">Queue Server</h2><div class="section-block">
<p>While building your web application, you may have some tasks, such as parsing and storing an uploaded CSV file, that take too long to perform during a typical web request. Thankfully, Fomo allows you to easily create queued jobs that may be processed in the background. By moving time intensive tasks to a queue, your application can respond to web requests with blazing speed and provide a better user experience to your customers.</p>
<p>Queues in Fomo are supported by redis</p>
<h3>start command</h3>
<p>You can use the following command to start the server</p>
<pre><code class="language-bash">php engineer queue:start</code></pre>
<h3>status command</h3>
<p>You can check the status of all processes with the following command</p>
<pre><code class="language-bash">php engineer queue:status</code></pre>
<h3>stop command</h3>
<p>You can stop the server with the following command</p>
<pre><code class="language-bash">php engineer queue:stop</code></pre>
<h3>Generating Job Classes</h3>
<p>By default, all of the queueable jobs for your application are stored in the app/Jobs directory. If the app/Jobs directory doesn't exist, it will be created when you run the build:job engineer command:</p>
<pre><code class="language-bash">php engineer build:job JobName</code></pre>
<h3>Class Structure</h3>
<p>Job classes are very simple, normally containing only a handle method that is invoked when the job is processed by the queue. To get started, let's take a look at an example job class. In this example, we'll pretend we manage a podcast publishing service and need to process the uploaded podcast files before they are published:</p>
<pre><code class="language-php">namespace App\Jobs;
use Fomo\Job\DispatchTrait;
class ProcessPodcast
{
use DispatchTrait;
public $podcast;
public function __construct(Podcast $podcast)
{
$this->podcast = $podcast;
}
public function handle()
{
// Process podcast...
}
}</code></pre>
<p>The handle method is invoked when the job is processed by the queue.</p>
<h3>Dispatching Jobs</h3>
<p>Once you have written your job class, you may dispatch it using the dispatch method on the job itself. The arguments passed to the dispatch method will be given to the job's constructor:</p>
<pre><code class="language-php">namespace App\Http\Controllers;
use App\Jobs\ProcessPodcast;
class PodcastController extends Controller
{
public function store(Request $request)
{
$podcast = DB::create(/* ... */);
// ...
ProcessPodcast::dispatch($podcast);
}
}</code></pre>
</div></section><section class="doc-section"><h2 class="section-title" id="scheduling-server">Scheduling Server</h2><div class="section-block">
<p>In the past, you may have written a cron configuration entry for every task you needed to schedule on your server. However, this can quickly become a pain because your job application is no longer in source control and you need to SSH into your server to view existing cron entries or add additional entries.</p>
<p>Fomo Command Scheduler offers a new approach to managing scheduled tasks on your server. The scheduler allows you to smoothly and clearly define the schedule of your commands in the Fomo app itself. When using scheduler, you don't need any cron entry on your server and all tasks are done through Fomo. The scheduling of your tasks is defined in the tasks method of the app/Scheduling/Kernel.php file. To help you get started, a simple example is defined inside the method.</p>
<h3>start command</h3>
<p>You can use the following command to start the server</p>
<pre><code class="language-bash">php engineer scheduling:start</code></pre>
<h3>status command</h3>
<p>You can check the status of all processes with the following command</p>
<pre><code class="language-bash">php engineer scheduling:status</code></pre>
<h3>stop command</h3>
<p>You can stop the server with the following command</p>
<pre><code class="language-bash">php engineer scheduling:stop</code></pre>
<h3>Generating Task Classes</h3>
<p>By default, all of the scheduling jobs for your application are stored in the app/Scheduling/Tasks directory. If the app/Scheduling/Tasks directory doesn't exist, it will be created when you run the build:task engineer command:</p>
<pre><code class="language-bash">php engineer build:task TaskName</code></pre>
<h3>Class Structure</h3>
<p>Task classes are very simple, usually containing only a handle method that is called by the scheduler when the task is processed.</p>
<pre><code class="language-php"><?php
namespace App\Scheduling\Tasks;
use Fomo\Database\DB;
class ClearTableTask
{
public function handle(): void
{
// Process
}
}</code></pre>
<h3>Defining Schedules</h3>
<p>You may define all of your scheduled tasks in the schedule method of your application's App\Scheduling\Kernel class. To get started, let's take a look at an example. In this example, we will schedule a closure to be called every day at midnight. Within the closure we will execute a database query to clear a table:</p>
<h6>app/Scheduling/Tasks/ClearTableTask.php</h6>
<pre><code class="language-php"><?php
namespace App\Scheduling\Tasks;
use Fomo\Database\DB;
class ClearTableTask
{
public function handle(): void
{
DB::table('recent_users')->delete();
}
}</code></pre>
<h6>app/Scheduling/Kernel.php</h6>
<pre><code class="language-php"><?php
namespace App\Scheduling;
use App\Scheduling\Tasks\ClearTableTask;
use Fomo\Scheduling\Scheduler;
class Kernel
{
public function tasks(): void
{
(new Scheduler())->call(ClearTableTask::class)->daily();
}
}</code></pre>
<h3>Schedule Frequency Options</h3>
<p>We've already seen a few examples of how you may configure a task to run at specified intervals. However, there are many more task schedule frequencies that you may assign to a task:</p>
<table class="table table-bordered">
<thead>
<tr>
<th>Method</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>->cron('* * * * *');</code></td>
<td>Run the task on a custom cron schedule</td>
</tr>
<tr>
<td><code>->everyMinute();</code></td>
<td>Run the task every minute</td>
</tr>
<tr>
<td><code>->everyTwoMinutes();</code></td>
<td>Run the task every two minutes</td>
</tr>
<tr>
<td><code>->everyThreeMinutes();</code></td>
<td>Run the task every three minutes</td>
</tr>
<tr>
<td><code>->everyFourMinutes();</code></td>
<td>Run the task every four minutes</td>
</tr>
<tr>
<td><code>->everyFiveMinutes();</code></td>
<td>Run the task every five minutes</td>
</tr>
<tr>
<td><code>->everyTenMinutes();</code></td>
<td>Run the task every ten minutes</td>
</tr>
<tr>
<td><code>->everyFifteenMinutes();</code></td>
<td>Run the task every fifteen minutes</td>
</tr>
<tr>
<td><code>->everyThirtyMinutes();</code></td>
<td>Run the task every thirty minutes</td>
</tr>
<tr>
<td><code>->hourly();</code></td>
<td>Run the task every hour</td>
</tr>
<tr>
<td><code>->hourlyAt(17);</code></td>
<td>Run the task every hour at 17 minutes past the hour</td>
</tr>
<tr>
<td><code>->everyOddHour();</code></td>
<td>Run the task every odd hour</td>
</tr>
<tr>
<td><code>->everyTwoHours();</code></td>
<td>Run the task every two hours</td>
</tr>
<tr>
<td><code>->everyThreeHours();</code></td>
<td>Run the task every three hours</td>
</tr>
<tr>
<td><code>->everyFourHours();</code></td>
<td>Run the task every four hours</td>
</tr>
<tr>
<td><code>->everySixHours();</code></td>
<td>Run the task every six hours</td>
</tr>
<tr>
<td><code>->daily();</code></td>
<td>Run the task every day at midnight</td>
</tr>
<tr>
<td><code>->dailyAt('13:00');</code></td>
<td>Run the task every day at 13:00</td>
</tr>
<tr>
<td><code>->twiceDaily(1, 13);</code></td>
<td>Run the task daily at 1:00 & 13:00</td>
</tr>
<tr>
<td><code>->twiceDailyAt(1, 13, 15);</code></td>
<td>Run the task daily at 1:15 & 13:15</td>