/** * Initialize phery by scanning the target class for response methods. * This eliminates the need for phery::instance->set( ... array of response methods ), for quick setup. * * An data-remote method defined on the client side should have a corresponding response method * with the same name prefixed by "ph_". Usage example: * * View: * <button data-remote="testmethod" >Call ph_testmethod in target class</button> * or equivalent * <?php echo phery::link_to('Call ajax_testmethod in target class', 'testmethod', array('tag' => 'button')); ?> * * Controller: * public function before() { * parent::before(); * Pheryajax::init($this); // <-- This init function looks for response method "phery_testmethod" in the controller itself ($this) * } * * public function phery_testmethod($data = NULL) { // <-- "ajax_testmethod" corresponding to client side "testmethod" * return PheryResponse::factory()->alert('Hello from ph_testmethod!'); * } * * @param $target_class where to look for methods that will be triggered by ajax calls * @param $phery_callbacks */ public static function init($target_class, $phery_callbacks = array()) { try { Phery::instance()->config(array('exceptions' => true, 'unobstructive' => array('thisone')))->callback($phery_callbacks)->set(self::get_response_methods($target_class))->process(); } catch (PheryException $exc) { echo PheryResponse::factory()->alert($exc->getMessage()); exit; } }
function data($ajax_data, $callback_data, Phery $phery) { return PheryResponse::factory($callback_data['submit_id'])->merge('scrollTop')->data('testing', array('nice' => 'awesome'))->jquery('div.test2')->css(array('backgroundColor' => '#f5a'))->animate(array('width' => "70%", 'opacity' => 0.8, 'marginLeft' => "0.6in", 'fontSize' => "1em", 'borderWidth' => "10px"), 1500, 'linear', PheryFunction::factory(<<<JSON \tfunction(){ \t\t\$(this).append("<br>yes Ive finished animating and fired from inside PHP as an animate() completion callback using PheryFunction rawr!"); \t} JSON )); }
public function after() { $this->ajax->config(array_replace($this->ajax_config, $this->ajax(), array('exit_allowed' => false, 'return' => true))); parent::after(); if (Phery::is_ajax(true)) { try { if (($response = $this->ajax->process()) !== false) { $this->response->headers(array('Content-Type' => 'application/json'))->body($response); } } catch (PheryException $exc) { Kohana::$log->add(Log::ERROR, $exc->getMessage()); $answer = PheryResponse::factory(); if ($exc->getCode() === Phery::ERROR_CSRF) { $answer->renew_csrf($this->ajax); } $this->response->headers(array('Content-Type' => 'application/json'))->body($answer); } } }
/** * Process the requests if any * * @param boolean $last_call * * @return boolean */ private function process_data($last_call) { $response = null; $error = null; $view = false; if (empty($_POST['phery'])) { return self::exception($this, 'Non-Phery AJAX request', self::ERROR_PROCESS); } if (!empty($_GET['_'])) { $this->data['requested'] = (int) $_GET['_']; unset($_GET['_']); } if (isset($_GET['_try_count'])) { $this->data['retries'] = (int) $_GET['_try_count']; unset($_GET['_try_count']); } $args = array(); $remote = false; if (!empty($_POST['phery']['remote'])) { $remote = $_POST['phery']['remote']; } if (!empty($_POST['phery']['submit_id'])) { $this->data['submit_id'] = "#{$_POST['phery']['submit_id']}"; } if ($remote !== false) { $this->data['remote'] = $remote; } if (!empty($_POST['args'])) { $args = get_magic_quotes_gpc() ? $this->stripslashes_recursive($_POST['args']) : $_POST['args']; if ($last_call === true) { unset($_POST['args']); } } foreach ($_POST['phery'] as $name => $post) { if (!isset($this->data[$name])) { $this->data[$name] = $post; } } if (count($this->callbacks['before'])) { foreach ($this->callbacks['before'] as $func) { if (($args = call_user_func($func, $args, $this->data, $this)) === false) { return false; } } } if (!empty($_POST['phery']['view'])) { $this->data['view'] = $_POST['phery']['view']; } if ($remote !== false) { if (isset($this->functions[$remote])) { if (isset($_POST['phery']['remote'])) { unset($_POST['phery']['remote']); } $this->before_user_func(); $response = call_user_func($this->functions[$remote], $args, $this->data, $this); foreach ($this->callbacks['after'] as $func) { if (call_user_func($func, $args, $this->data, $response, $this) === false) { return false; } } if (($response = self::respond($response, false)) === null) { $error = 'Response was void for function "' . htmlentities($remote, ENT_COMPAT, null, false) . '"'; } $_POST['phery']['remote'] = $remote; } else { if ($last_call) { self::exception($this, 'The function provided "' . htmlentities($remote, ENT_COMPAT, null, false) . '" isn\'t set', self::ERROR_PROCESS); } } } else { if (!empty($this->data['view']) && isset($this->views[$this->data['view']])) { $view = $this->data['view']; $this->before_user_func(); $response = call_user_func($this->views[$this->data['view']], $args, $this->data, $this); foreach ($this->callbacks['after'] as $func) { if (call_user_func($func, $args, $this->data, $response, $this) === false) { return false; } } if (($response = self::respond($response, false)) === null) { $error = 'Response was void for view "' . htmlentities($this->data['view'], ENT_COMPAT, null, false) . '"'; } } else { if ($last_call) { if (!empty($this->data['view'])) { self::exception($this, 'The provided view "' . htmlentities($this->data['view'], ENT_COMPAT, null, false) . '" isn\'t set', self::ERROR_PROCESS); } else { self::exception($this, 'Empty request', self::ERROR_PROCESS); } } } } if ($error !== null) { self::error_handler(E_NOTICE, $error, '', 0); } elseif ($response === null && $last_call & !$view) { $response = PheryResponse::factory(); } elseif ($response !== null) { ob_start(); if (!$this->config['return']) { echo $response; } } if (!$this->config['return'] && $this->config['exit_allowed'] === true) { if ($last_call || $response !== null) { exit; } } elseif ($this->config['return']) { self::flush(true); } if ($this->config['error_reporting'] !== false) { restore_error_handler(); } return $response; }