1. Go to this page and download the library: Download lechimp-p/php-formlets library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
lechimp-p / php-formlets example snippets
// We propably use a better autoloader in a real setting.
t from an ordinary PHP function. Since explode takes
// two mandatory and one optional parameter, we have to explicitly tell how many
// optional parameters we want to have.
$explode = F::fun("explode", 2);
// For the lib to work, we need to treat functions and values the same,
// so we need to lift ordinary values to our abstraction.
$delim = F::val(" ");
$string = F::val("foo bar");
// We could apply the function once to the delim, creating a new function.
$explodeBySpace = $explode->apply($delim);
// We could apply the function to the string to create the final result:
$res = $explodeBySpace->apply($string);
// Since the value is still wrapped, we need to unwrap it.
$unwrapped = $res->get();
echo "Array containing \"foo\" and \"bar\":\n";
print_r($unwrapped);
$throws = F::fun(function ($foo) {
throw new Exception("I knew this would happen.");
return $foo;
});
$throwsAndCatches = $throws->catchAndReify("Exception");
$res = $throwsAndCatches->apply(F::val("But it won't..."));
echo "This will state my hindsight:\n";
echo ($res->isError()?$res->error():$res->get())."\n";
// Really not too interesting, but we need to use our value abstraction.
$boringFormlet = F::inject(F::val("Hello World!"));
// Since functions are values as well, we could construct a formlet containing
// a function.
$functionFormlet = F::inject($explodeBySpace);
// We need to specify an id for the form and an action target.
$form = F::form("boring", "www.example.com", $boringFormlet);
// We initialize the form with an empty input array. One could
// use init without args to use $_POST as input.
$form->init(array());
// Renderer does nothing
echo "This will show \"No content\":\n";
echo ("<form method=\"post\" action=\"www.example.com\"></form>" == $form->html()
? "No content\n"
: "Oh, that's not pure...\n"
);
// The form has a constant result as expected.
echo "This will show \"Hello World!\":\n";
echo $form->result()."\n";
// The function to map over the formlet is called mapCollector, since it leaves
// the builder untouched. Maybe at some point a mapRenderer might come in handy
// too...
$containsArrayFormlet = $boringFormlet->map($explodeBySpace);
$form = F::form("contains_array", "www.example.com", $containsArrayFormlet);
$form->init(array());
echo "Array containing \"Hello\" and \"World!\":\n";
print_r($form->result());
// Will be a lot more interesting when you see formlets that actually take some
// input.
$exploded = F::inject($explode)
->cmb(F::inject($delim))
->cmb(F::inject($string))
;
$form = F::form("explode", "www.example.com", $exploded);
$form->init(array());
echo "Array containing \"foo\" and \"bar\":\n";
print_r($form->result());
// fun also supports defining some fixed arguments.
$containsHello = F::fun("preg_match", 2, array("/.*hello.*/i"));
// Append the predicate to a formlet. If its not truthy for the value in the
// formlet, an error value with the given message will be collected.
$withPred = F::inject(F::val("Hi there."))
->satisfies($containsHello, "You should say hello.");
$form = F::form("with_pred", "www.example.com", $withPred);
$form->init(array());
echo "This will be stating, what you should say:\n";
echo ($form->wasSuccessfull() ? $form->result() : $form->error())."\n";
// Maybe next time we'll use a Wheel as example.
class _Date {
public function __construct($y, $m, $d) {
if (!is_int($y) || !is_int($m) || !is_int($d)) {
throw new Exception("Expected int's as input.");
}
if ($m < 1 || $m > 12) {
throw new Exception("Invalid month: '%m'.");
}
if ($d > 31) {
throw new Exception("Invalid day: '%d'.");
}
if ($m === 2 && $d > 29) {
throw new Exception("Month is 2 but day is $d.");
}
if (in_array($m, array(4,6,9,11)) && $d > 30) {
throw new Exception("Month is $m but day is $d.");
}
$this->y = $y;
$this->m = $m;
$this->d = $d;
}
public function toISO() {
return $this->y."-".$this->m."-".$this->d;
}
}
// Our constructor function. We want to catch Exceptions since the constructor
// of the class could throw. In the real world we would be more specific
// on the type of exception we want to catch.
$mkDate = F::fun(function ($y, $m, $d) {
return new _Date($y, $m, $d);
})
->catchAndReify("Exception")
;
function inRange($l, $r) {
return F::fun(function($value) use ($l, $r) {
return $value >= $l && $value <= $r;
});
}
// First we create an integer input from a text input by map intval over the
// string input after checking it is indeed an integer. We also want to
// display the errors.
$int_formlet = F::with_errors(F::text_input())
->satisfies(F::fun("is_numeric"), "No integer.")
->map(F::fun("intval", 1))
;
// From the integer input we'll create a month and day input by doing further
// checks on the input. Make sure you understand, that none of these touches
// the int_formlet, but rather creates new objects.
$month_formlet = $int_formlet
->satisfies(inRange(1,12), "Month must have value between 1 and 12.")
;
$day_formlet = $int_formlet
->satisfies(inRange(1,31), "Day must have value between 1 and 31.")
;
// We use a convenience function here to not have cmb that often.
$date_formlet = F::formlet(
F::inject($mkDate),
F::text("\n\t"), // for readability on cli only
F::with_label("Year: ", $int_formlet),
F::text("\n\t"), // for readability on cli only
F::with_label("Month: ", $month_formlet),
F::text("\n\t"), // for readability on cli only
F::with_label("Day: ", $day_formlet),
F::text("\n") // for readability on cli only
);
// You got that step, right?
$form = F::form("date", "www.example.com", $date_formlet);
$form->init(array());
// First look at the rendering:
echo "This will show some date input in HTML representation:\n";
echo $form->html()."\n\n";
// Then lets look at the collected values. Since we don't actually POST the
// form, we need to mock up some input.
$mock_post1 = array( "date_input_0" => "2014"
, "date_input_1" => "12"
, "date_input_2" => "24"
);
// We could use init without parameters if we wanted to use $_POST as input.
$form->init($mock_post1);
echo "This will show a date of christmas eve:\n";
echo $form->result()->toISO()."\n\n";
// To see how errors will show up in the formlets, lets try the same with faulty
// input:
$mock_post2 = array( "date_input_0" => "2014"
, "date_input_1" => "12"
, "date_input_2" => "32" // that would make a long month
);
$form->init($mock_post2);
echo "This will tell why creation of date object did not work:\n";
echo ($form->wasSuccessfull() ? $form->result()->toISO() : $form->error())."\n\n";
// So there's something wrong, and we most likely want to reprompt the user with
// the form, stating the problem.
echo "This will show some HTML of the formlet with error messages:\n";
echo $form->html();
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.