Source for file encoding.php

Documentation is available at encoding.php

  1. <?php
  2. /**
  3.  *  base include file for SimpleTest
  4.  *  @package    SimpleTest
  5.  *  @subpackage WebTester
  6.  *  @version    $Id: encoding.php 1723 2008-04-08 00:34:10Z lastcraft $
  7.  */
  8.     
  9. /**#@+
  10.  *  include other SimpleTest class files
  11.  */
  12. require_once(dirname(__FILE__'/socket.php');
  13. /**#@-*/
  14.  
  15.  *    Single post parameter.
  16.  *    @package SimpleTest
  17.  *    @subpackage WebTester
  18.  */
  19.     var $_key;
  20.     var $_value;
  21.     
  22.     /**
  23.      *    Stashes the data for rendering later.
  24.      *    @param string $key       Form element name.
  25.      *    @param string $value     Data to send.
  26.      */
  27.     function SimpleEncodedPair($key$value{
  28.         $this->_key = $key;
  29.         $this->_value = $value;
  30.     }
  31.     
  32.     /**
  33.      *    The pair as a single string.
  34.      *    @return string        Encoded pair.
  35.      *    @access public
  36.      */
  37.     function asRequest({
  38.         return urlencode($this->_key'=' urlencode($this->_value);
  39.     }
  40.     
  41.     /**
  42.      *    The MIME part as a string.
  43.      *    @return string        MIME part encoding.
  44.      *    @access public
  45.      */
  46.     function asMime({
  47.         $part 'Content-Disposition: form-data; ';
  48.         $part .= "name=\"" $this->_key . "\"\r\n";
  49.         $part .= "\r\n" $this->_value;
  50.         return $part;
  51.     }
  52.     
  53.     /**
  54.      *    Is this the value we are looking for?
  55.      *    @param string $key    Identifier.
  56.      *    @return boolean       True if matched.
  57.      *    @access public
  58.      */
  59.     function isKey($key{
  60.         return $key == $this->_key;
  61.     }
  62.     
  63.     /**
  64.      *    Is this the value we are looking for?
  65.      *    @return string       Identifier.
  66.      *    @access public
  67.      */
  68.     function getKey({
  69.         return $this->_key;
  70.     }
  71.     
  72.     /**
  73.      *    Is this the value we are looking for?
  74.      *    @return string       Content.
  75.      *    @access public
  76.      */
  77.     function getValue({
  78.         return $this->_value;
  79.     }
  80. }
  81.  
  82. /**
  83.  *    Single post parameter.
  84.  *    @package SimpleTest
  85.  *    @subpackage WebTester
  86.  */
  87.     var $_key;
  88.     var $_content;
  89.     var $_filename;
  90.     
  91.     /**
  92.      *    Stashes the data for rendering later.
  93.      *    @param string $key          Key to add value to.
  94.      *    @param string $content      Raw data.
  95.      *    @param hash $filename       Original filename.
  96.      */
  97.     function SimpleAttachment($key$content$filename{
  98.         $this->_key = $key;
  99.         $this->_content = $content;
  100.         $this->_filename = $filename;
  101.     }
  102.     
  103.     /**
  104.      *    The pair as a single string.
  105.      *    @return string        Encoded pair.
  106.      *    @access public
  107.      */
  108.     function asRequest({
  109.         return '';
  110.     }
  111.     
  112.     /**
  113.      *    The MIME part as a string.
  114.      *    @return string        MIME part encoding.
  115.      *    @access public
  116.      */
  117.     function asMime({
  118.         $part 'Content-Disposition: form-data; ';
  119.         $part .= 'name="' $this->_key . '"; ';
  120.         $part .= 'filename="' $this->_filename . '"';
  121.         $part .= "\r\nContent-Type: " $this->_deduceMimeType();
  122.         $part .= "\r\n\r\n" $this->_content;
  123.         return $part;
  124.     }
  125.     
  126.     /**
  127.      *    Attempts to figure out the MIME type from the
  128.      *    file extension and the content.
  129.      *    @return string        MIME type.
  130.      *    @access private
  131.      */
  132.     function _deduceMimeType({
  133.         if ($this->_isOnlyAscii($this->_content)) {
  134.             return 'text/plain';
  135.         }
  136.         return 'application/octet-stream';
  137.     }
  138.     
  139.     /**
  140.      *    Tests each character is in the range 0-127.
  141.      *    @param string $ascii    String to test.
  142.      *    @access private
  143.      */
  144.     function _isOnlyAscii($ascii{
  145.         for ($i 0$length strlen($ascii)$i $length$i++{
  146.             if (ord($ascii[$i]127{
  147.                 return false;
  148.             }
  149.         }
  150.         return true;
  151.     }
  152.     
  153.     /**
  154.      *    Is this the value we are looking for?
  155.      *    @param string $key    Identifier.
  156.      *    @return boolean       True if matched.
  157.      *    @access public
  158.      */
  159.     function isKey($key{
  160.         return $key == $this->_key;
  161.     }
  162.     
  163.     /**
  164.      *    Is this the value we are looking for?
  165.      *    @return string       Identifier.
  166.      *    @access public
  167.      */
  168.     function getKey({
  169.         return $this->_key;
  170.     }
  171.     
  172.     /**
  173.      *    Is this the value we are looking for?
  174.      *    @return string       Content.
  175.      *    @access public
  176.      */
  177.     function getValue({
  178.         return $this->_filename;
  179.     }
  180. }
  181.  
  182. /**
  183.  *    Bundle of GET/POST parameters. Can include
  184.  *    repeated parameters.
  185.  *    @package SimpleTest
  186.  *    @subpackage WebTester
  187.  */
  188. class SimpleEncoding {
  189.     var $_request;
  190.     
  191.     /**
  192.      *    Starts empty.
  193.      *    @param array $query       Hash of parameters.
  194.      *                               Multiple values are
  195.      *                               as lists on a single key.
  196.      *    @access public
  197.      */
  198.     function SimpleEncoding($query false{
  199.         if ($query{
  200.             $query array();
  201.         }
  202.         $this->clear();
  203.         $this->merge($query);
  204.     }
  205.     
  206.     /**
  207.      *    Empties the request of parameters.
  208.      *    @access public
  209.      */
  210.     function clear({
  211.         $this->_request = array();
  212.     }
  213.     
  214.     /**
  215.      *    Adds a parameter to the query.
  216.      *    @param string $key            Key to add value to.
  217.      *    @param string/array $value    New data.
  218.      *    @access public
  219.      */
  220.     function add($key$value{
  221.         if ($value === false{
  222.             return;
  223.         }
  224.         if (is_array($value)) {
  225.             foreach ($value as $item{
  226.                 $this->_addPair($key$item);
  227.             }
  228.         else {
  229.             $this->_addPair($key$value);
  230.         }
  231.     }
  232.     
  233.     /**
  234.      *    Adds a new value into the request.
  235.      *    @param string $key            Key to add value to.
  236.      *    @param string/array $value    New data.
  237.      *    @access private
  238.      */
  239.     function _addPair($key$value{
  240.         $this->_request[new SimpleEncodedPair($key$value);
  241.     }
  242.     
  243.     /**
  244.      *    Adds a MIME part to the query. Does nothing for a
  245.      *    form encoded packet.
  246.      *    @param string $key          Key to add value to.
  247.      *    @param string $content      Raw data.
  248.      *    @param hash $filename       Original filename.
  249.      *    @access public
  250.      */
  251.     function attach($key$content$filename{
  252.         $this->_request[new SimpleAttachment($key$content$filename);
  253.     }
  254.     
  255.     /**
  256.      *    Adds a set of parameters to this query.
  257.      *    @param array/SimpleQueryString $query  Multiple values are
  258.      *                                            as lists on a single key.
  259.      *    @access public
  260.      */
  261.     function merge($query{
  262.         if (is_object($query)) {
  263.             $this->_request = array_merge($this->_request$query->getAll());
  264.         elseif (is_array($query)) {
  265.             foreach ($query as $key => $value{
  266.                 $this->add($key$value);
  267.             }
  268.         }
  269.     }
  270.     
  271.     /**
  272.      *    Accessor for single value.
  273.      *    @return string/array    False if missing, string
  274.      *                             if present and array if
  275.      *                             multiple entries.
  276.      *    @access public
  277.      */
  278.     function getValue($key{
  279.         $values array();
  280.         foreach ($this->_request as $pair{
  281.             if ($pair->isKey($key)) {
  282.                 $values[$pair->getValue();
  283.             }
  284.         }
  285.         if (count($values== 0{
  286.             return false;
  287.         elseif (count($values== 1{
  288.             return $values[0];
  289.         else {
  290.             return $values;
  291.         }
  292.     }
  293.     
  294.     /**
  295.      *    Accessor for listing of pairs.
  296.      *    @return array        All pair objects.
  297.      *    @access public
  298.      */
  299.     function getAll({
  300.         return $this->_request;
  301.     }
  302.     
  303.     /**
  304.      *    Renders the query string as a URL encoded
  305.      *    request part.
  306.      *    @return string        Part of URL.
  307.      *    @access protected
  308.      */
  309.     function _encode({
  310.         $statements array();
  311.         foreach ($this->_request as $pair{
  312.             if ($statement $pair->asRequest()) {
  313.                 $statements[$statement;
  314.             }
  315.         }
  316.         return implode('&'$statements);
  317.     }
  318. }
  319.  
  320. /**
  321.  *    Bundle of GET parameters. Can include
  322.  *    repeated parameters.
  323.  *    @package SimpleTest
  324.  *    @subpackage WebTester
  325.  */
  326. class SimpleGetEncoding extends SimpleEncoding {
  327.     
  328.     /**
  329.      *    Starts empty.
  330.      *    @param array $query       Hash of parameters.
  331.      *                               Multiple values are
  332.      *                               as lists on a single key.
  333.      *    @access public
  334.      */
  335.     function SimpleGetEncoding($query false{
  336.         $this->SimpleEncoding($query);
  337.     }
  338.     
  339.     /**
  340.      *    HTTP request method.
  341.      *    @return string        Always GET.
  342.      *    @access public
  343.      */
  344.     function getMethod({
  345.         return 'GET';
  346.     }
  347.     
  348.     /**
  349.      *    Writes no extra headers.
  350.      *    @param SimpleSocket $socket        Socket to write to.
  351.      *    @access public
  352.      */
  353.     function writeHeadersTo(&$socket{
  354.     }
  355.     
  356.     /**
  357.      *    No data is sent to the socket as the data is encoded into
  358.      *    the URL.
  359.      *    @param SimpleSocket $socket        Socket to write to.
  360.      *    @access public
  361.      */
  362.     function writeTo(&$socket{
  363.     }
  364.     
  365.     /**
  366.      *    Renders the query string as a URL encoded
  367.      *    request part for attaching to a URL.
  368.      *    @return string        Part of URL.
  369.      *    @access public
  370.      */
  371.     function asUrlRequest({
  372.         return $this->_encode();
  373.     }
  374. }
  375.  
  376. /**
  377.  *    Bundle of URL parameters for a HEAD request.
  378.  *    @package SimpleTest
  379.  *    @subpackage WebTester
  380.  */
  381.     
  382.     /**
  383.      *    Starts empty.
  384.      *    @param array $query       Hash of parameters.
  385.      *                               Multiple values are
  386.      *                               as lists on a single key.
  387.      *    @access public
  388.      */
  389.     function SimpleHeadEncoding($query false{
  390.         $this->SimpleGetEncoding($query);
  391.     }
  392.     
  393.     /**
  394.      *    HTTP request method.
  395.      *    @return string        Always HEAD.
  396.      *    @access public
  397.      */
  398.     function getMethod({
  399.         return 'HEAD';
  400.     }
  401. }
  402.  
  403. /**
  404.  *    Bundle of POST parameters. Can include
  405.  *    repeated parameters.
  406.  *    @package SimpleTest
  407.  *    @subpackage WebTester
  408.  */
  409.     
  410.     /**
  411.      *    Starts empty.
  412.      *    @param array $query       Hash of parameters.
  413.      *                               Multiple values are
  414.      *                               as lists on a single key.
  415.      *    @access public
  416.      */
  417.     function SimplePostEncoding($query false{
  418.         if (is_array($queryand $this->hasMoreThanOneLevel($query)) {
  419.             $query $this->rewriteArrayWithMultipleLevels($query);
  420.         }
  421.         $this->SimpleEncoding($query);
  422.     }
  423.     
  424.     function hasMoreThanOneLevel($query{
  425.         foreach ($query as $key => $value{
  426.             if (is_array($value)) {
  427.                 return true;
  428.             }
  429.         }
  430.         return false;
  431.     }
  432.  
  433.     function rewriteArrayWithMultipleLevels($query{
  434.         $query_ array();
  435.         foreach ($query as $key => $value{
  436.             if (is_array($value)) {
  437.                 foreach ($value as $sub_key => $sub_value{
  438.                     $query_[$key."[".$sub_key."]"$sub_value;
  439.                 }
  440.             else {
  441.                 $query_[$key$value;
  442.             }
  443.         }
  444.         if ($this->hasMoreThanOneLevel($query_)) {
  445.             $query_ $this->rewriteArrayWithMultipleLevels($query_);
  446.         }
  447.         
  448.         return $query_;
  449.     }
  450.     
  451.     
  452.     /**
  453.      *    HTTP request method.
  454.      *    @return string        Always POST.
  455.      *    @access public
  456.      */
  457.     function getMethod({
  458.         return 'POST';
  459.     }
  460.     
  461.     /**
  462.      *    Dispatches the form headers down the socket.
  463.      *    @param SimpleSocket $socket        Socket to write to.
  464.      *    @access public
  465.      */
  466.     function writeHeadersTo(&$socket{
  467.         $socket->write("Content-Length: " . (integer)strlen($this->_encode()) "\r\n");
  468.         $socket->write("Content-Type: application/x-www-form-urlencoded\r\n");
  469.     }
  470.     
  471.     /**
  472.      *    Dispatches the form data down the socket.
  473.      *    @param SimpleSocket $socket        Socket to write to.
  474.      *    @access public
  475.      */
  476.     function writeTo(&$socket{
  477.         $socket->write($this->_encode());
  478.     }
  479.     
  480.     /**
  481.      *    Renders the query string as a URL encoded
  482.      *    request part for attaching to a URL.
  483.      *    @return string        Part of URL.
  484.      *    @access public
  485.      */
  486.     function asUrlRequest({
  487.         return '';
  488.     }
  489. }
  490.  
  491. /**
  492.  *    Bundle of POST parameters in the multipart
  493.  *    format. Can include file uploads.
  494.  *    @package SimpleTest
  495.  *    @subpackage WebTester
  496.  */
  497.     var $_boundary;
  498.     
  499.     /**
  500.      *    Starts empty.
  501.      *    @param array $query       Hash of parameters.
  502.      *                               Multiple values are
  503.      *                               as lists on a single key.
  504.      *    @access public
  505.      */
  506.     function SimpleMultipartEncoding($query false$boundary false{
  507.         $this->SimplePostEncoding($query);
  508.         $this->_boundary = ($boundary === false uniqid('st'$boundary);
  509.     }
  510.     
  511.     /**
  512.      *    Dispatches the form headers down the socket.
  513.      *    @param SimpleSocket $socket        Socket to write to.
  514.      *    @access public
  515.      */
  516.     function writeHeadersTo(&$socket{
  517.         $socket->write("Content-Length: " . (integer)strlen($this->_encode()) "\r\n");
  518.         $socket->write("Content-Type: multipart/form-data, boundary=" $this->_boundary . "\r\n");
  519.     }
  520.     
  521.     /**
  522.      *    Dispatches the form data down the socket.
  523.      *    @param SimpleSocket $socket        Socket to write to.
  524.      *    @access public
  525.      */
  526.     function writeTo(&$socket{
  527.         $socket->write($this->_encode());
  528.     }
  529.     
  530.     /**
  531.      *    Renders the query string as a URL encoded
  532.      *    request part.
  533.      *    @return string        Part of URL.
  534.      *    @access public
  535.      */
  536.     function _encode({
  537.         $stream '';
  538.         foreach ($this->_request as $pair{
  539.             $stream .= "--" $this->_boundary . "\r\n";
  540.             $stream .= $pair->asMime("\r\n";
  541.         }
  542.         $stream .= "--" $this->_boundary . "--\r\n";
  543.         return $stream;
  544.     }
  545. }
  546. ?>

Documentation generated on Sun, 04 May 2008 09:21:31 -0500 by phpDocumentor 1.3.0