AJAX
[ class tree: AJAX ] [ index: AJAX ] [ all elements ]

Source for file Server.php

Documentation is available at Server.php

  1. <?php
  2. /**
  3.  * OO AJAX Implementation for PHP
  4.  *
  5.  * @category   HTML
  6.  * @package    AJAX
  7.  * @author     Joshua Eichorn <josh@bluga.net>
  8.  * @copyright  2005 Joshua Eichorn
  9.  * @license    http://www.opensource.org/licenses/lgpl-license.php  LGPL
  10.  * @version    Release: @package_version@
  11.  */
  12.  
  13. /**
  14.  * Require the main AJAX library
  15.  */
  16. require_once 'HTML/AJAX.php';
  17.  
  18. /**
  19.  * Class for creating an external AJAX server
  20.  *
  21.  * Can be used in 2 different modes, registerClass mode where you create an instance of the server and add the classes that will be registered
  22.  * and then run handle request
  23.  *
  24.  * Or you can extend it and add init{className} methods for each class you want to export
  25.  *
  26.  * Client js generation is exposed through 2 _GET params client and stub
  27.  *  Setting the _GET param client to `all` will give you all the js classes needed
  28.  *  Setting the _GET param stub to `all` will give you stubs of all registered classes, you can also set it too just 1 class
  29.  *
  30.  * @category   HTML
  31.  * @package    AJAX
  32.  * @author     Joshua Eichorn <josh@bluga.net>
  33.  * @copyright  2005 Joshua Eichorn
  34.  * @license    http://www.opensource.org/licenses/lgpl-license.php  LGPL
  35.  * @version    Release: @package_version@
  36.  * @link       http://pear.php.net/package/PackageName
  37.  */
  38. {
  39.  
  40.     /**
  41.      * Client options array if set to true the code looks at _GET
  42.      * @var bool|array
  43.      */
  44.     var $options = true;
  45.  
  46.     /**
  47.      * HTML_AJAX instance
  48.      * @var HTML_AJAX 
  49.      */
  50.     var $ajax;
  51.  
  52.     /**
  53.      * Set to true if your extending the server to add init{className methods}
  54.      * @var boolean 
  55.      * @access  public
  56.      */
  57.     var $initMethods = false;
  58.  
  59.     /**
  60.      * Location on filesystem of client javascript library
  61.      * @var false|stringif false the default pear data dir location is used
  62.      */
  63.     var $clientJsLocation = false;
  64.  
  65.     /** 
  66.      * An array of options that tell the server howto Cache output
  67.      *
  68.      * The rules are functions that make etag hash used to see if the client needs to download updated content
  69.      * If you extend this class you can make your own rule function the naming convention is _cacheRule{RuleName}
  70.      *
  71.      * <code>
  72.      * array(
  73.      *  'httpCacheClient' => true,   // send 304 headers for responses to ?client=* requests
  74.      *  'ClientCacheRule' => 'File', // create a hash from file names and modified times, options: file|content
  75.      *  'ClientCacheExpects'=> 'files', // what type of content to send to the hash function, options: files|classes|content
  76.      *  'httpCacheStub'   => true,   // send 304 headers for responses to ?stub=* requests
  77.      *  'StubCacheRule'   => 'Api',  // create a hash from the exposed api, options: api|content
  78.      *  'StubCacheExpects'=> 'classes', // what type of content to send to the hash function, options: files|classes|content
  79.      * )
  80.      * </code>
  81.      *
  82.      * @var array 
  83.      * @access  public
  84.      */
  85.     var $cacheOptions = array(
  86.         'httpCacheClient'       => true
  87.         'ClientCacheRule'       => 'file',
  88.         'ClientCacheExpects'    => 'files',
  89.         'httpCacheStub'         => true
  90.         'StubCacheRule'         => 'api'
  91.         'StubCacheExpects'      => 'classes'
  92.         );
  93.  
  94.     /**
  95.      * Compression Options
  96.      *
  97.      * <code>
  98.      * array(
  99.      *  'enabled'   => false,   // enable compression
  100.      *  'type'      => 'gzip'   // the type of compression to do, options: gzip
  101.      * )
  102.      * </code>
  103.      *
  104.      * @var array 
  105.      * @access public
  106.      */
  107.     var $compression = array(
  108.         'enabled'       => false,
  109.         'type'          => 'gzip'
  110.     );
  111.  
  112.     /**
  113.      * Javascript library names and there path
  114.      *
  115.      * the return of $this->clientJsLocation(), is prepended before running readfile on them
  116.      *
  117.      * @access  public
  118.      * @var array 
  119.      */
  120.     var $javascriptLibraries = array(
  121.         'all'           =>  'HTML_AJAX.js',
  122.         'html_ajax'     =>  'HTML_AJAX.js',
  123.         'html_ajax_lite'=>  'HTML_AJAX_lite.js',
  124.         'json'          =>  'serializer/JSON.js',
  125.         'request'       =>  'Request.js',
  126.         'main'          =>  array('Compat.js','Main.js','clientPool.js'),
  127.         'httpclient'    =>  'HttpClient.js',
  128.         'dispatcher'    =>  'Dispatcher.js',
  129.         'util'          =>  'util.js',
  130.         'loading'       =>  'Loading.js',
  131.         'phpserializer' =>  'serializer/phpSerializer.js',
  132.         'urlserializer' =>  'serializer/UrlSerializer.js',
  133.         'haserializer'  =>  'serializer/haSerializer.js',
  134.         'clientpool'    =>  'clientPool.js',
  135.         'iframe'        =>  'IframeXHR.js',
  136.         'alias'         =>  'Alias.js',
  137.         'queues'        =>  'Queue.js',
  138.         'behavior'      =>  array('behavior/behavior.js','behavior/cssQuery-p.js'),
  139.  
  140.         // rules to help you use a minimal library set
  141.         'standard'      =>  array('Compat.js','clientPool.js','util.js','Main.js','HttpClient.js','Request.js','serializer/JSON.js',
  142.                                     'Loading.js','serializer/UrlSerializer.js','Alias.js','behavior/behavior.js','behavior/cssQuery-p.js'),
  143.         'jsonrpc'       =>  array('Compat.js','util.js','Main.js','clientPool.js','HttpClient.js','Request.js','serializer/JSON.js'),
  144.         'proxyobjects'  =>  array('Compat.js','util.js','Main.js','clientPool.js','Request.js','serializer/JSON.js','Dispatcher.js'),
  145.  
  146.         // BC rules
  147.         'priorityqueue' =>  'Queue.js',
  148.         'orderedqueue'  =>  'Queue.js',
  149.     );
  150.  
  151.     /**
  152.      * Custom paths to use for javascript libraries, if not set {@link clientJsLocation} is used to find the system path
  153.      *
  154.      * @access public
  155.      * @var array 
  156.      * @see registerJsLibrary
  157.      */
  158.     var $javascriptLibraryPaths = array();
  159.  
  160.     /**
  161.      * Array of className => init methods to call, generated from constructor from initClassName methods
  162.      *
  163.      * @access protected
  164.      */
  165.     var $_initLookup = array();
  166.     
  167.  
  168.     /**
  169.      * Constructor creates the HTML_AJAX instance
  170.      *
  171.      * @param string $serverUrl (Optional) the url the client should be making a request too
  172.      */
  173.     function HTML_AJAX_Server($serverUrl = false
  174.     {
  175.         $this->ajax = new HTML_AJAX();
  176.  
  177.         // parameters for HTML::AJAX
  178.         $parameters = array('stub''client');
  179.  
  180.         // keep in the query string all the parameters that don't belong to AJAX
  181.         // we remove all string like "parameter=something&". Final '&' can also
  182.         // be '&amp;' (to be sure) and is optional. '=something' is optional too.
  183.         $querystring '';
  184.         if (isset($_SERVER['QUERY_STRING'])) {
  185.             $querystring preg_replace('/(' join('|'$parameters')(?:=[^&]*(?:&(?:amp;)?|$))?/'''$this->ajax->_getServer('QUERY_STRING'));
  186.         }
  187.  
  188.         // call the server with this query string
  189.         if ($serverUrl === false{
  190.             $serverUrl htmlentities($this->ajax->_getServer('PHP_SELF'));
  191.         }
  192.  
  193.         if (substr($serverUrl,-1!= '?'{
  194.             $serverUrl .= '?';
  195.         }
  196.         $this->ajax->serverUrl =  $serverUrl htmlentities($querystring);
  197.         
  198.         $methods get_class_methods($this);
  199.         foreach($methods as $method{
  200.             if (preg_match('/^init([a-zA-Z0-9_]+)$/',$method,$match)) {
  201.                 $this->_initLookup[strtolower($match[1])$method;
  202.             }
  203.         }
  204.     }
  205.  
  206.     /**
  207.      * Handle a client request, either generating a client or having HTML_AJAX handle the request
  208.      *
  209.      * @return boolean true if request was handled, false otherwise
  210.      */
  211.     function handleRequest(
  212.     {
  213.         if ($this->options == true{
  214.             $this->_loadOptions();
  215.         }
  216.         //basically a hook for iframe but allows processing of data earlier
  217.         $this->ajax->populatePayload();
  218.         if (!isset($_GET['c']&& (count($this->options['client']> 0 || count($this->options['stub']> 0) ) {
  219.             $this->generateClient();
  220.             return true;
  221.         else {
  222.             if (!empty($_GET['c'])) {
  223.                 $this->_init($this->_cleanIdentifier($this->ajax->_getVar('c')));
  224.             }
  225.             return $this->ajax->handleRequest();
  226.         }
  227.     }
  228.  
  229.     /**
  230.      * Register method passthrough to HTML_AJAX
  231.      *
  232.      * @see HTML_AJAX::registerClass for docs
  233.      */
  234.     function registerClass(&$instance$exportedName = false$exportedMethods = false
  235.     {
  236.         $this->ajax->registerClass($instance,$exportedName,$exportedMethods);
  237.     }
  238.  
  239.     /**
  240.      * Change default serialization - important for exporting classes
  241.      *
  242.      * I wanted this for the xml serializer :)
  243.      */
  244.     function setSerializer($type
  245.     {
  246.         $this->ajax->serializer = $type;
  247.         $this->ajax->unserializer = $type;
  248.     }
  249.  
  250.     /**
  251.      * Register a new js client library
  252.      *
  253.      * @param string          $libraryName name you'll reference the library as
  254.      * @param string|array   $fileName   actual filename with no path, for example customLib.js
  255.      * @param string|false   $path   Optional, if not set the result from jsClientLocation is used
  256.      */
  257.     function registerJSLibrary($libraryName,$fileName,$path = false{
  258.         $libraryName strtolower($libraryName);
  259.         $this->javascriptLibraries[$libraryName$fileName;
  260.  
  261.         if ($path !== false{
  262.             $this->javascriptLibraryPaths[$libraryName$path;
  263.         }
  264.     }
  265.  
  266.     /**
  267.      * Register init methods from an external class
  268.      *
  269.      * @param object    $instance an external class with initClassName methods
  270.      */
  271.     function registerInitObject(&$instance{
  272.         $instance->server =$this;
  273.         $methods get_class_methods($instance);
  274.         foreach($methods as $method{
  275.             if (preg_match('/^init([a-zA-Z0-9_]+)$/',$method,$match)) {
  276.                 $this->_initLookup[strtolower($match[1])= array(&$instance,$method);
  277.             }
  278.         }
  279.     }
  280.  
  281.     /**
  282.      * Register a callback to be exported to the client
  283.      *
  284.      * This function uses the PHP callback pseudo-type
  285.      *
  286.      */
  287.     function registerPhpCallback($callback)
  288.     {
  289.         if (!is_callable($callback)) {
  290.             // invalid callback
  291.             return false;
  292.         }
  293.         
  294.         if (is_array($callback&& is_object($callback[0])) {
  295.             // object method
  296.             $this->registerClass($callback[0]strtolower(get_class($callback[0]))array($callback[1]));
  297.             return true;
  298.         }
  299.         
  300.         // static callback
  301.         $this->ajax->registerPhpCallback($callback);
  302.     }
  303.  
  304.     /**
  305.      * Generate client js
  306.      *
  307.      * @todo    this is going to need tests to cover all the options
  308.      */
  309.     function generateClient(
  310.     {
  311.         $headers = array();
  312.  
  313.         ob_start();
  314.  
  315.         // create a list list of js files were going to need to output
  316.         // index is the full file and so is the value, this keeps duplicates out of $fileList
  317.         $fileList = array();
  318.  
  319.         if(!is_array($this->options['client'])) {
  320.             $this->options['client'= array();
  321.         }
  322.         foreach($this->options['client'as $library{
  323.             if (isset($this->javascriptLibraries[$library])) {
  324.                 $lib = (array)$this->javascriptLibraries[$library];
  325.                 foreach($lib as $file{
  326.                     if (isset($this->javascriptLibraryPaths[$library])) {
  327.                         $fileList[$this->javascriptLibraryPaths[$library].$file$this->javascriptLibraryPaths[$library].$file;
  328.                     }
  329.                     else {
  330.                         $fileList[$this->clientJsLocation().$file$this->clientJsLocation().$file;
  331.                     }
  332.                 }
  333.             }
  334.         }
  335.  
  336.         // do needed class init if were running an init server
  337.         if(!is_array($this->options['stub'])) {
  338.             $this->options['stub'= array();
  339.         }
  340.         $classList $this->options['stub'];
  341.         if ($this->initMethods{
  342.             if (isset($this->options['stub'][0]&& $this->options['stub'][0=== 'all'{
  343.                     $this->_initAll();
  344.             else {
  345.                 foreach($this->options['stub'as $stub{
  346.                     $this->_init($stub);
  347.                 }
  348.             }
  349.         }
  350.         if (isset($this->options['stub'][0]&& $this->options['stub'][0=== 'all'{
  351.             $classList array_keys($this->ajax->_exportedInstances);
  352.         }
  353.  
  354.         // if were doing stub and client we have to wait for both ETags before we can compare with the client
  355.         $combinedOutput = false;
  356.         if ($classList != false && count($classList> 0 && count($fileList> 0{
  357.             $combinedOutput = true;
  358.         }
  359.  
  360.  
  361.         if ($classList != false && count($classList> 0{
  362.  
  363.             // were setup enough to make a stubETag if the input it wants is a class list
  364.             if ($this->cacheOptions['httpCacheStub'&& 
  365.                 $this->cacheOptions['StubCacheExpects'== 'classes'
  366.             {
  367.                 $stubETag $this->_callCacheRule('Stub',$classList);
  368.             }
  369.  
  370.             // if were not in combined output compare etags, if method returns true were done
  371.             if (!$combinedOutput && isset($stubETag)) {
  372.                 if ($this->_compareEtags($stubETag)) {
  373.                     ob_end_clean();
  374.                     return;
  375.                 }
  376.             }
  377.  
  378.             // output the stubs for all the classes in our list
  379.             foreach($classList as $class{
  380.                     echo $this->ajax->generateClassStub($class);
  381.             }
  382.  
  383.             // if were cacheing and the rule expects content make a tag and check it, if the check is true were done
  384.             if ($this->cacheOptions['httpCacheStub'&& 
  385.                 $this->cacheOptions['StubCacheExpects'== 'content'
  386.             {
  387.                 $stubETag $this->_callCacheRule('Stub',ob_get_contents());
  388.             }
  389.  
  390.             // if were not in combined output compare etags, if method returns true were done
  391.             if (!$combinedOutput && isset($stubETag)) {
  392.                 if ($this->_compareEtags($stubETag)) {
  393.                     ob_end_clean();
  394.                     return;
  395.                 }
  396.             }
  397.         }
  398.  
  399.         if (count($fileList> 0{
  400.             // if were caching and need a file list build our jsETag
  401.             if ($this->cacheOptions['httpCacheClient'&& 
  402.                 $this->cacheOptions['ClientCacheExpects'=== 'files'
  403.             {
  404.                 $jsETag $this->_callCacheRule('Client',$fileList);
  405.  
  406.             }
  407.  
  408.             // if were not in combined output compare etags, if method returns true were done
  409.             if (!$combinedOutput && isset($jsETag)) {
  410.                 if ($this->_compareEtags($jsETag)) {
  411.                     ob_end_clean();
  412.                     return;
  413.                 }
  414.             }
  415.  
  416.             // output the needed client js files
  417.             foreach($fileList as $file{
  418.                 $this->_readFile($file);
  419.             }
  420.  
  421.             // if were caching and need content build the etag
  422.             if ($this->cacheOptions['httpCacheClient'&& 
  423.                 $this->cacheOptions['ClientCacheExpects'=== 'content'
  424.             {
  425.                 $jsETag $this->_callCacheRule('Client',ob_get_contents());
  426.             }
  427.  
  428.             // if were not in combined output compare etags, if method returns true were done
  429.             if (!$combinedOutput && isset($jsETag)) {
  430.                 if ($this->_compareEtags($jsETag)) {
  431.                     ob_end_clean();
  432.                     return;
  433.                 }
  434.             }
  435.             // were in combined output, merge the 2 ETags and compare
  436.             else if (isset($jsETag&& isset($stubETag)) {
  437.                 if ($this->_compareEtags(md5($stubETag.$jsETag))) {
  438.                     ob_end_clean();
  439.                     return;
  440.                 }
  441.             }
  442.         }
  443.  
  444.  
  445.         // were outputting content, add our length header and send the output
  446.         $length ob_get_length();
  447.         $output ob_get_contents();
  448.         ob_end_clean();
  449.  
  450.         if ($this->ajax->packJavaScript{
  451.             $output $this->ajax->packJavaScript($output);
  452.             $length strlen($output);
  453.         }
  454.  
  455.         if ($this->compression['enabled'&& $this->compression['type'== 'gzip' && strpos($_SERVER["HTTP_ACCEPT_ENCODING"]"gzip"!== false{
  456.             $output gzencode($output,9);
  457.             $length strlen($output);
  458.             $headers['Content-Encoding''gzip';
  459.         }
  460.  
  461.         if ($length > 0 && $this->ajax->_sendContentLength()) 
  462.             $headers['Content-Length'$length;
  463.         }
  464.         $headers['Content-Type''text/javascript; charset=utf-8';
  465.         $this->ajax->_sendHeaders($headers);
  466.         echo($output);
  467.     }
  468.  
  469.     /**
  470.      * Run readfile on input with basic error checking
  471.      *
  472.      * @param   string  $file   file to read
  473.      * @access  private
  474.      * @todo    is addslashes enough encoding for js?
  475.      */
  476.     function _readFile($file
  477.     {
  478.         if (file_exists($file)) {
  479.             readfile($file);
  480.         else {
  481.             $file addslashes($file);
  482.             echo "alert('Unable to find javascript file: $file');";
  483.         }
  484.     }
  485.  
  486.     /**
  487.      * Get the location of the client js
  488.      * To override the default pear datadir location set $this->clientJsLocation
  489.      *
  490.      * @return  string 
  491.      */
  492.     function clientJsLocation(
  493.     {
  494.         if (!$this->clientJsLocation{
  495.             $path '@data-dir@'.DIRECTORY_SEPARATOR.'HTML_AJAX'.DIRECTORY_SEPARATOR.'js'.DIRECTORY_SEPARATOR;
  496.             if(strpos($path'@'.'data-dir@'=== 0)
  497.             {
  498.                 $path realpath(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'js').DIRECTORY_SEPARATOR;
  499.             }
  500.             return $path;
  501.         else {
  502.             return $this->clientJsLocation;
  503.         }
  504.     }
  505.  
  506.     /**
  507.      * Set the location of the client js
  508.      *
  509.      * @access  public
  510.      * @param   string  $location   Location
  511.      * @return  void 
  512.      */
  513.     function setClientJsLocation($location
  514.     {
  515.         $this->clientJsLocation = $location;
  516.     }
  517.  
  518.     /**
  519.      * Set the path to a Javascript libraries
  520.      *
  521.      * @access  public
  522.      * @param   string  $library    Library name
  523.      * @param   string  $path       Path
  524.      * @return  void 
  525.      */
  526.     function setJavascriptLibraryPath($library$path
  527.     {
  528.         $this->javascriptLibraryPaths[$library$path;
  529.     }
  530.  
  531.     /**
  532.      * Set the path to more than one Javascript libraries at once
  533.      *
  534.      * @access  public
  535.      * @param   array   $paths  Paths
  536.      * @return  void 
  537.      */
  538.     function setJavascriptLibraryPaths($paths
  539.     {
  540.         if (is_array($paths)) {
  541.             $this->javascriptLibraryPaths = array_merge($this->javascriptLibraryPaths$paths);
  542.         }
  543.     }
  544.  
  545.     /**
  546.      * Load options from _GET
  547.      *
  548.      * @access private
  549.      */
  550.     function _loadOptions(
  551.     {
  552.         $this->options = array('client'=>array(),'stub'=>array());
  553.         if (isset($_GET['client'])) {
  554.             $clients explode(',',$this->ajax->_getVar('client'));
  555.             $client = array();
  556.             foreach($clients as $val{
  557.                 $cleanVal $this->_cleanIdentifier($val);
  558.                 if (!empty($cleanVal)) {
  559.                     $client[strtolower($cleanVal);
  560.                 }
  561.             }
  562.  
  563.             if (count($client> 0{
  564.                 $this->options['client'$client;
  565.             }
  566.         }
  567.         if (isset($_GET['stub'])) {
  568.             $stubs explode(',',$this->ajax->_getVar('stub'));
  569.             $stub = array();
  570.             foreach($stubs as $val{
  571.                 $cleanVal $this->_cleanIdentifier($val);
  572.                 if (!empty($cleanVal)) {
  573.                     $stub[strtolower($cleanVal);
  574.                 }
  575.             }
  576.  
  577.             if (count($stub> 0{
  578.                 $this->options['stub'$stub;
  579.             }
  580.         }
  581.     }
  582.  
  583.     /**
  584.      * Clean an identifier like a class name making it safe to use
  585.      *
  586.      * @param   string  $input 
  587.      * @return  string 
  588.      * @access  private
  589.      */
  590.     function _cleanIdentifier($input{
  591.             return trim(preg_replace('/[^A-Za-z_0-9]/','',$input));
  592.     }
  593.  
  594.     /**
  595.      * Run every init method on the class
  596.      *
  597.      * @access private
  598.      */
  599.     function _initAll(
  600.     {
  601.         if ($this->initMethods{
  602.             foreach($this->_initLookup as $class => $method{
  603.                 $this->_init($class);
  604.             }
  605.         }
  606.     }
  607.  
  608.     /**
  609.      * Init one class
  610.      *
  611.      * @param   string  $className 
  612.      * @access private
  613.      */
  614.     function _init($className
  615.     {
  616.         $className strtolower($className);
  617.         if ($this->initMethods{
  618.             if (isset($this->_initLookup[$className])) {
  619.                 $method =$this->_initLookup[$className];
  620.                 if (is_array($method)) {
  621.                     call_user_func($method);
  622.                 }
  623.                 else {
  624.                     $this->$method();
  625.                 }
  626.             else {
  627.                 trigger_error("Could find an init method for class: " $className);
  628.             }
  629.         }
  630.     }
  631.  
  632.     /**
  633.      * Generate a hash from a list of files
  634.      *
  635.      * @param   array   $files  file list
  636.      * @return  string  a hash that can be used as an etag
  637.      * @access  private
  638.      */
  639.     function _cacheRuleFile($files{
  640.         $signature "";
  641.         foreach($files as $file{
  642.             if (file_exists($file)) {
  643.                 $signature .= $file.filemtime($file);
  644.             }
  645.         }
  646.         return md5($signature);
  647.     }
  648.  
  649.     /**
  650.      * Generate a hash from the api of registered classes
  651.      *
  652.      * @param   array   $classes class list
  653.      * @return  string  a hash that can be used as an etag
  654.      * @access  private
  655.      */
  656.     function _cacheRuleApi($classes{
  657.         $signature "";
  658.         foreach($classes as $class{
  659.             if (isset($this->ajax->_exportedInstances[$class])) {
  660.                 $signature .= $class.implode(',',$this->ajax->_exportedInstances[$class]['exportedMethods']);
  661.             }
  662.         }
  663.         return md5($signature);
  664.     }
  665.  
  666.     /**
  667.      * Generate a hash from the raw content
  668.      *
  669.      * @param   array   $content 
  670.      * @return  string  a hash that can be used as an etag
  671.      * @access  private
  672.      */
  673.     function _cacheRuleContent($content{
  674.         return md5($content);
  675.     }
  676.  
  677.     /**
  678.      * Send cache control headers
  679.      * @access  private
  680.      */
  681.     function _sendCacheHeaders($etag,$notModified{
  682.         header('Cache-Control: must-revalidate');
  683.         header('ETag: '.$etag);
  684.         if ($notModified{
  685.             header('HTTP/1.0 304 Not Modified',false,304);
  686.         }
  687.     }
  688.  
  689.     /**
  690.      * Compare eTags
  691.      *
  692.      * @param   string  $serverETag server eTag
  693.      * @return  boolean 
  694.      * @access  private
  695.      */
  696.     function _compareEtags($serverETag{
  697.         if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
  698.             if (strcmp($this->ajax->_getServer('HTTP_IF_NONE_MATCH'),$serverETag== 0{
  699.                 $this->_sendCacheHeaders($serverETag,true);
  700.                 return true;
  701.             }
  702.         }
  703.         $this->_sendCacheHeaders($serverETag,false);
  704.         return false;
  705.     }
  706.  
  707.     /**
  708.      * Call a cache rule and return its retusn
  709.      *
  710.      * @param   string  $rule Stub|Client
  711.      * @param   mixed   $payload 
  712.      * @return  boolean 
  713.      * @access  private
  714.      * @todo    decide if error checking is needed
  715.      */
  716.     function _callCacheRule($rule,$payload{
  717.         $method '_cacheRule'.$this->cacheOptions[$rule.'CacheRule'];
  718.         return call_user_func(array(&$this,$method),$payload);
  719.     }
  720. }
  721. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  722. ?>

Documentation generated on Fri, 04 Apr 2008 18:30:25 -0400 by phpDocumentor 1.4.0. PEAR Logo Copyright © PHP Group 2004.