/vendor/anahkiasen/former/src/Former/Former.php
PHP | 489 lines | 265 code | 53 blank | 171 comment | 14 complexity | 0c65e36191013d00d403c982b375f854 MD5 | raw file
- <?php
- namespace Former;
- use Closure;
- use Former\Exceptions\InvalidFrameworkException;
- use Former\Traits\Field;
- use Illuminate\Container\Container;
- use Illuminate\Support\MessageBag;
- use Illuminate\Contracts\Validation\Validator;
- /**
- * Helps the user interact with the various Former components
- */
- class Former
- {
- // Instances
- ////////////////////////////////////////////////////////////////////
- /**
- * The current environment
- *
- * @var \Illuminate\Container\Container
- */
- protected $app;
- /**
- * The Method Dispatcher
- *
- * @var MethodDispatcher
- */
- protected $dispatch;
- // Informations
- ////////////////////////////////////////////////////////////////////
- /**
- * The form's errors
- *
- * @var Message
- */
- protected $errors;
- /**
- * An array of rules to use
- *
- * @var array
- */
- protected $rules = array();
- /**
- * An array of field macros
- *
- * @var array
- */
- protected $macros = array();
- /**
- * The labels created so far
- *
- * @var array
- */
- public $labels = array();
- /**
- * The IDs created so far
- *
- * @var array
- */
- public $ids = array();
- /**
- * A lookup table where the key is the input name,
- * and the value is number of times seen. This is
- * used to calculate unique ids.
- *
- * @var array
- */
- public $names = array();
- // Namespaces
- ////////////////////////////////////////////////////////////////////
- /**
- * The namespace of Form elements
- */
- const FORMSPACE = 'Former\Form\\';
- /**
- * The namespace of fields
- */
- const FIELDSPACE = 'Former\Form\Fields\\';
- /**
- * Build a new Former instance
- *
- * @param Container $app
- * @param MethodDispatcher $dispatcher
- */
- public function __construct(Container $app, MethodDispatcher $dispatcher)
- {
- $this->app = $app;
- $this->dispatch = $dispatcher;
- }
- ////////////////////////////////////////////////////////////////////
- //////////////////////////// INTERFACE /////////////////////////////
- ////////////////////////////////////////////////////////////////////
- /**
- * Acts as a router that redirects methods to all of Former classes
- *
- * @param string $method The method called
- * @param array $parameters An array of parameters
- *
- * @return mixed
- */
- public function __call($method, $parameters)
- {
- // Dispatch to Form\Elements
- // Explicitly check false since closeGroup() may return an empty string
- if (($element = $this->dispatch->toElements($method, $parameters)) !== false) {
- return $element;
- }
- // Dispatch to Form\Form
- if ($form = $this->dispatch->toForm($method, $parameters)) {
- $this->app->instance('former.form', $form);
- return $this->app['former.form'];
- }
- // Dispatch to Form\Group
- if ($group = $this->dispatch->toGroup($method, $parameters)) {
- return $group;
- }
- // Dispatch to Form\Actions
- if ($actions = $this->dispatch->toActions($method, $parameters)) {
- return $actions;
- }
- // Dispatch to macros
- if ($macro = $this->dispatch->toMacros($method, $parameters)) {
- return $macro;
- }
- // Checking for any supplementary classes
- $classes = explode('_', $method);
- $method = array_pop($classes);
- // Dispatch to the different Form\Fields
- $framework = isset($this->app['former.form.framework']) ? $this->app['former.form.framework'] : $this->app['former.framework'];
- $field = $this->dispatch->toFields($method, $parameters);
- if ($field instanceof Field) {
- $field = $framework->getFieldClasses($field, $classes);
- }
- // Else bind field
- $this->app->instance('former.field', $field);
- return $this->app['former.field'];
- }
- ////////////////////////////////////////////////////////////////////
- //////////////////////////////// MACROS ////////////////////////////
- ////////////////////////////////////////////////////////////////////
- /**
- * Register a macro with Former
- *
- * @param string $name The name of the macro
- * @param Callable $macro The macro itself
- *
- * @return mixed
- */
- public function macro($name, $macro)
- {
- $this->macros[$name] = $macro;
- }
- /**
- * Check if a macro exists
- *
- * @param string $name
- *
- * @return boolean
- */
- public function hasMacro($name)
- {
- return isset($this->macros[$name]);
- }
- /**
- * Get a registered macro
- *
- * @param string $name
- *
- * @return Closure
- */
- public function getMacro($name)
- {
- return $this->macros[$name];
- }
- ////////////////////////////////////////////////////////////////////
- ///////////////////////////// POPULATOR ////////////////////////////
- ////////////////////////////////////////////////////////////////////
- /**
- * Add values to populate the array
- *
- * @param mixed $values Can be an Eloquent object or an array
- */
- public function populate($values)
- {
- $this->app['former.populator']->replace($values);
- }
- /**
- * Set the value of a particular field
- *
- * @param string $field The field's name
- * @param mixed $value Its new value
- */
- public function populateField($field, $value)
- {
- $this->app['former.populator']->put($field, $value);
- }
- /**
- * Get the value of a field
- *
- * @param string $field The field's name
- * @param null $fallback
- *
- * @return mixed
- */
- public function getValue($field, $fallback = null)
- {
- return $this->app['former.populator']->get($field, $fallback);
- }
- /**
- * Fetch a field value from both the new and old POST array
- *
- * @param string $name A field name
- * @param string $fallback A fallback if nothing was found
- *
- * @return string The results
- */
- public function getPost($name, $fallback = null)
- {
- $name = str_replace(array('[', ']'), array('.', ''), $name);
- $name = trim($name, '.');
- $oldValue = $this->app['request']->old($name, $fallback);
- return $this->app['request']->input($name, $oldValue, true);
- }
- ////////////////////////////////////////////////////////////////////
- ////////////////////////////// TOOLKIT /////////////////////////////
- ////////////////////////////////////////////////////////////////////
- /**
- * Set the errors to use for validations
- *
- * @param Message $validator The result from a validation
- *
- * @return void
- */
- public function withErrors($validator = null)
- {
- // Try to get the errors form the session
- if ($this->app['session']->has('errors')) {
- $this->errors = $this->app['session']->get('errors');
- }
- // If we're given a raw Validator, go fetch the errors in it
- if ($validator instanceof Validator) {
- $this->errors = $validator->getMessageBag();
- } else {
- if ($validator instanceof MessageBag) {
- $this->errors = $validator;
- }
- }
- return $this->errors;
- }
- /**
- * Add live validation rules
- *
- * @param array *$rules An array of Laravel rules
- *
- * @return void
- */
- public function withRules()
- {
- $rules = call_user_func_array('array_merge', func_get_args());
- // Parse the rules according to Laravel conventions
- foreach ($rules as $name => $fieldRules) {
- $expFieldRules = $fieldRules;
- if (!is_array($expFieldRules)) {
- $expFieldRules = explode('|', $expFieldRules);
- $expFieldRules = array_map('trim', $expFieldRules);
- }
- foreach ($expFieldRules as $rule) {
- $parameters = null;
- // If we have a rule with a value
- if (($colon = strpos($rule, ':')) !== false) {
- $parameters = str_getcsv(substr($rule, $colon + 1));
- }
- // Exclude unsupported rules
- $rule = is_numeric($colon) ? substr($rule, 0, $colon) : $rule;
- // Store processed rule in Former's array
- if (!isset($parameters)) {
- $parameters = array();
- }
- $this->rules[$name][$rule] = $parameters;
- }
- }
- }
- /**
- * Switch the framework used by Former
- *
- * @param string $framework The name of the framework to use
- */
- public function framework($framework = null)
- {
- if (!$framework) {
- return $this->app['former.framework']->current();
- }
- $this->setOption('framework', $framework);
- $framework = $this->getFrameworkInstance($framework);
- $this->app->bind('former.framework', function ($app) use ($framework) {
- return $framework;
- });
- }
- /**
- * Get a new framework instance
- *
- * @param string $framework
- *
- * @throws Exceptions\InvalidFrameworkException
- * @return \Former\Interfaces\FrameworkInterface
- */
- public function getFrameworkInstance($framework)
- {
- $formerClass = __NAMESPACE__.'\Framework\\'.$framework;
- //get interfaces of the given framework
- $interfaces = class_exists($framework) ? class_implements($framework) : array();
- if(class_exists($formerClass)) {
- $returnClass = $formerClass;
- } elseif(class_exists($framework) && isset($interfaces['Former\Interfaces\FrameworkInterface'])) {
- // We have some outside class, lets return it.
- $returnClass = $framework;
- } else {
- throw (new InvalidFrameworkException())->setFramework($framework);
- }
- return new $returnClass($this->app);
- }
- /**
- * Get an option from the config
- *
- * @param string $option The option
- * @param mixed $default Optional fallback
- *
- * @return mixed
- */
- public function getOption($option, $default = null)
- {
- return $this->app['config']->get('former.'.$option, $default);
- }
- /**
- * Set an option on the config
- *
- * @param string $option
- * @param string $value
- */
- public function setOption($option, $value)
- {
- return $this->app['config']->set('former.'.$option, $value);
- }
- ////////////////////////////////////////////////////////////////////
- ////////////////////////////// BUILDERS ////////////////////////////
- ////////////////////////////////////////////////////////////////////
- /**
- * Closes a form
- *
- * @return string A form closing tag
- */
- public function close()
- {
- if ($this->app->bound('former.form')) {
- $closing = $this->app['former.form']->close();
- }
- // Destroy instances
- $instances = array('former.form', 'former.form.framework');
- foreach ($instances as $instance) {
- $this->app[$instance] = null;
- unset($this->app[$instance]);
- }
- // Reset populator
- $this->app['former.populator']->reset();
- // Reset all values
- $this->errors = null;
- $this->rules = array();
- return isset($closing) ? $closing : null;
- }
- ////////////////////////////////////////////////////////////////////
- ////////////////////////////// HELPERS /////////////////////////////
- ////////////////////////////////////////////////////////////////////
- /**
- * Get the errors for the current field
- *
- * @param string $name A field name
- *
- * @return string An error message
- */
- public function getErrors($name = null)
- {
- // Get name and translate array notation
- if (!$name and $this->app['former.field']) {
- $name = $this->app['former.field']->getName();
- // Always return empty string for anonymous fields (i.e. fields with no name/id)
- if (!$name) {
- return '';
- }
- }
- if ($this->errors and $name) {
- $name = str_replace(array('[', ']'), array('.', ''), $name);
- $name = trim($name, '.');
- return $this->errors->first($name);
- }
- return $this->errors;
- }
- /**
- * Get a rule from the Rules array
- *
- * @param string $name The field to fetch
- *
- * @return array An array of rules
- */
- public function getRules($name)
- {
- // Check the rules for the name as given
- $ruleset = array_get($this->rules, $name);
- // If no rules found, convert to dot notation and try again
- if (is_null($ruleset)) {
- $name = str_replace(array('[', ']'), array('.', ''), $name);
- $name = trim($name, '.');
- $ruleset = array_get($this->rules, $name);
- }
- return $ruleset;
- }
- }