<commit_before><?php

/**
 * Distribute a route and payload to the proper handler.
 * http://www.phpchatscript.com
 *
 * Copyright (c) 2012 "delphian" <NAME>
 * Licensed under the MIT license.
 */

/**
 * @code
 *  // Create server.
 *  $server = Server::load($config);
 *  // Craete plugin.
 *  class MyPlugin {
 *    protected static $routes = array('/myplugin/one', '/myplugin/two');
 *  }
 *  // Register plugin to handle routes.
 *  $server->register_handler('MyPlugin', MyPlugin::routes);
 *  // Get the request from $_GET, $_POST, or a plugin.
 *  $server->receive_request();
 *  // Run the server. Invoke all plugins registered for this route.
 *  $server->process_request();
 *  // Close down the server gracefully.
 *  $server->halt();
 * @endcode
 */

class Server extends Observed {

  /** Keep track of our singletons based on their class names. */
  protected static $singletons = array();

  /** Routes are url paths. A route determines where a payload will end up.
      This is the currentl url path that was requested of us. */
  private $route = NULL;

  /** Payload set by the caller before receive_message() is invoked. This is
      where the parameters to the observer are placed. */
  protected $payload = NULL;
  /** User will be set by the caller before receive_message() is invoked. This
      contains the authenticated user which is accessing the server. */
  protected $user = NULL;
  /** Response sent to the calling class at end of execution. When each plugin
      is finished executing it will set the $output property of its calling
      class. */
  protected $output = NULL;
  /** Response sent to the client at end of execution. This array will be json
      encoded before being output. If this value is not empty then the above
      $output variable will be ignored in favore of $json_output. */
  protected $json_output = NULL;

  /**
   * Constructor. We will force the use of SingletonLoader::load() even if
   * The requesting code tries to instantiate a new class by hand.
   */
  public function __construct() {
    /** Retrieve the name of the concrete class being instantiated. */
    $class = get_called_class();
    /** If a singleton does not exist then create it. */
    if (array_key_exists($class, self::$singletons) === FALSE) {
      self::$singletons[$class] = $this;
    }

    return self::$singletons[$class];
  }

  /**
   * Retrieve the route and payload from the submission.
   *
   * Hooks will be invoked to allow plugins to alter the route, alter the
   * payload, and alter the logged in user (if any).
   *
   * @return $this->route
   *   The current route, or NULL on failure.
   */
  public function receive_request() {
    /** Get the route from the url. The route is the url. */
    $route = '/';
    if (isset($_REQUEST['route'])) {
      $route = $_REQUEST['route'];
    }
    $this->set_route($route);
    /** Plugins may alter the route. */
    $this->invoke_all('__route');

    /** Grab our payload (parameters to the route handler). */
    if (isset($_GET['payload'])) {
      if (!$this->set_payload($_GET['payload'])) {
        if (isset($_POST['payload'])) {
          $this->set_payload($_POST['payload']);
        }
      }
    }
    /** Plugins may alter the payload. */
    $this->invoke_all('__payload');

    /** Its up to the plugins to set the user property. This property is
        used to determine if a user is logged into the server and will contain
        information about the user. */
    $this->invoke_all('__user');

    return $this->route;
  }

  /**
   * Execute the route recieved and pass the payload to the 
   * appropriate handler.
   */
  public function process_request() {
    $this->log(__CLASS__, __METHOD__);
    switch ($this->route) {
      case '__version':
        $this->headers[] = 'Content-Type: text/plain';
        $this->headers[] = 'Cache-Control: no-cache, must-revalidate';
        $this->headers[] = 'Expires: Sat, 26 Jul 1997 05:00:00 GMT';
        $this->output = '0.4.8';
        break;
    }

    /** Call all plugin handlers. */
    $this->invoke_all($this->route);
  }

  /**
   * Log the current server state into a text file.
   *
   * @param string $class
   *   Class that is invoking log, generally __CLASS__.
   * @param string $method
   *   Method that is invoking log, generally __METHOD__.
   *
   * @return bool TRUE
   *   TRUE on success, throws error on failure.
   */
  public function log($class = NULL, $method = NULL) {
/*
    $output = array(
      'time'    => time(),
      'class'   => $class,
      'method'  => $method,
      'route'   => $this->route,
      'payload' => $this->payload,
      'output'  => $this->output,
    );
    $handle = (file_exists($file)) ? fopen($file, 'a') : fopen($file, 'w');
    if ($handle) {
      $encoded = json_encode($output) . "\n";
      if (!$x = fwrite($handle, $encoded)) {
        throw new Exception('Could not write to variables file.');
      }
      fclose($handle);
    } else {
      throw new Exception('Could not open variable file for writing.');
    }
*/
    return TRUE;
  }

  /**
   * Clean up gracefully before ending server operation. This must be called
   * as the last activity before the script ends.
   */
  public function halt() {
    parent::halt();

    /** Send out our headers. */
    if (isset($this->output['headers'])) {
      if (is_array($this->output['headers'])) {
        foreach ($this->output['headers'] as $header) {
          header($header);
        }
      }
      else {
        throw new Exception('Headers must be array');
      }
    }
    /** Send out our output. */
    print $this->output['body'];

    return;
  }

  /**
   * Get property.
   *
   * @return Subject::$payload
   */
  public function get_payload() {
    return $this->payload;
  }

  /**
   * Get property.
   */
  public function get_output() {
    return $this->output;
  }

  /**
   * Get property.
   */
  public function get_user() {
    return $this->user;
  }

  /**
   * Receive our route and make sure its safe.
   *<commit_msg>Server will now default to returning json_output if any structure is present.<commit_after><?php

/**
 * Distribute a route and payload to the proper handler.
 * http://www.phpchatscript.com
 *
 * Copyright (c) 2012 "delphian" <NAME>
 * Licensed under the MIT license.
 */

/**
 * @code
 *  // Create server.
 *  $server = Server::load($config);
 *  // Craete plugin.
 *  class MyPlugin {
 *    protected static $routes = array('/myplugin/one', '/myplugin/two');
 *  }
 *  // Register plugin to handle routes.
 *  $server->register_handler('MyPlugin', MyPlugin::routes);
 *  // Get the request from $_GET, $_POST, or a plugin.
 *  $server->receive_request();
 *  // Run the server. Invoke all plugins registered for this route.
 *  $server->process_request();
 *  // Close down the server gracefully.
 *  $server->halt();
 * @endcode
 */

class Server extends Observed {

  /** Keep track of our singletons based on their class names. */
  protected static $singletons = array();

  /** Routes are url paths. A route determines where a payload will end up.
      This is the currentl url path that was requested of us. */
  private $route = NULL;

  /** Payload set by the caller before receive_message() is invoked. This is
      where the parameters to the observer are placed. */
  protected $payload = NULL;
  /** User will be set by the caller before receive_message() is invoked. This
      contains the authenticated user which is accessing the server. */
  protected $user = NULL;
  /** Response sent to the calling class at end of execution. When each plugin
      is finished executing it will set the $output property of its calling
      class. */
  protected $output = NULL;
  /** Response sent to the client at end of execution. This array will be json
      encoded before being output. If this value is not empty then the above
      $output variable will be ignored in favore of $json_output. */
  protected $json_output = NULL;

  /**
   * Constructor. We will force the use of SingletonLoader::load() even if
   * The requesting code tries to instantiate a new class by hand.
   */
  public function __construct() {
    /** Retrieve the name of the concrete class being instantiated. */
    $class = get_called_class();
    /** If a singleton does not exist then create it. */
    if (array_key_exists($class, self::$singletons) === FALSE) {
      self::$singletons[$class] = $this;
    }

    return self::$singletons[$class];
  }

  /**
   * Retrieve the route and payload from the submission.
   *
   * Hooks will be invoked to allow plugins to alter the route, alter the
   * payload, and alter the logged in user (if any).
   *
   * @return $this->route
   *   The current route, or NULL on failure.
   */
  public function receive_request() {
    /** Get the route from the url. The route is the url. */
    $route = '/';
    if (isset($_REQUEST['route'])) {
      $route = $_REQUEST['route'];
    }
    $this->set_route($route);
    /** Plugins may alter the route. */
    $this->invoke_all('__route');

    /** Grab our payload (parameters to the route handler). */
    if (isset($_GET['payload'])) {
      if (!$this->set_payload($_GET['payload'])) {
        if (isset($_POST['payload'])) {
          $this->set_payload($_POST['payload']);
        }
      }
    }
    /** Plugins may alter the payload. */
    $this->invoke_all('__payload');

    /** Its up to the plugins to set the user property. This property is
        used to determine if a user is logged into the server and will contain
        information about the user. */
    $this->invoke_all('__user');

    return $this->route;
  }

  /**
   * Execute the route recieved and pass the payload to the 
   * appropriate handler.
   */
  public function process_request() {
    $this->log(__CLASS__, __METHOD__);
    switch ($this->route) {
      case '__version':
        $this->headers[] = 'Content-Type: text/plain';
        $this->headers[] = 'Cache-Control: no-cache, must-revalidate';
        $this->headers[] = 'Expires: Sat, 26 Jul 1997 05:00:00 GMT';
        $this->output = '0.4.8';
        break;
    }

    /** Call all plugin handlers. */
    $this->invoke_all($this->route);
  }

  /**
   * Log the current server state into a text file.
   *
   * @param string $class
   *   Class that is invoking log, generally __CLASS__.
   * @param string $method
   *   Method that is invoking log, generally __METHOD__.
   *
   * @return bool TRUE
   *   TRUE on success, throws error on failure.
   */
  public function log($class = NULL, $method = NULL) {
/*
    $output = array(
      'time'    => time(),
      'class'   => $class,
      'method'  => $method,
      'route'   => $this->route,
      'payload' => $this->payload,
      'output'  => $this->output,
    );
    $handle = (file_exists($file)) ? fopen($file, 'a') : fopen($file, 'w');
    if ($handle) {
      $encoded = json_encode($output) . "\n";
      if (!$x = fwrite($handle, $encoded)) {
        throw new Exception('Could not write to variables file.');
      }
      fclose($handle);
    } else {
      throw new Exception('Could not open variable file for writing.');
    }
*/
    return TRUE;
  }

  /**
   * Clean up gracefully before ending server operation. This must be called
   * as the last activity before the script ends.
   */
  public function halt() {
    parent::halt();

    /** Send out our headers. */
    if (isset($this->output['headers'])) {
      if (is_array($this->output['headers'])) {
        foreach ($this->output['headers'] as $header) {
          header($header);
        }
      }
      else {
        throw new Exception('Headers must be array');
      }
    }
    /** Send out our output. */
    if (!empty($this->json_output)) {
      print json_encode($this->json_output);
    }
    else {
      print $this->output['body'];
    }

    return;
  }

  /**
   * Get property.
   *
   * @return Subject::$payload
   */
  public function get_payload() {
    return $this->payload;
  }

  /**
   * Get property.
   */
  public function get_output() {
    return $this->output;
  }

  /**
   * Get property.
   */
  public function get_user() {
    return $this->user;
  }

  /**
   * Receive our route and make sure its safe.
   *
{'fraction_non_alphanumeric': 0.13591205211726384, 'fraction_numerical': 0.003094462540716612, 'mean_word_length': 2.5638421358096344, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 79, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1946333', 'n_tokens_mistral': 3622, 'n_tokens_neox': 3543, 'n_words': 1258}