public function handleException($exception) { // load the renderer $render = \Painless::load('system/common/render'); var_dump($exception); die; }
public function response($status, $message, $payload = array()) { $response = \Painless::load('system/workflow/response', \Painless::LP_LOAD_NEW); $response->status = (int) $status; $response->message = $message; $response->payload = $payload; return $response; }
public static function init() { // Check if there's a trigger configuration $config = \Painless::load('system/common/config'); $triggers = $config->get('triggers.*'); if (!empty($triggers)) { foreach ($triggers as $name => $callback) { self::register($name, $callback); } } }
/** * Returns a list of actions supported by this workflow * @return array an array of actions/methods supported by this workflow */ public function options() { $request = \Painless::load('system/common/router/response'); $methods = $request->getMethodList(); // Run through the list of methods supported by the request object and then // cross-reference them to the list of methods available on this workflow. // If they don't exist, simply remove them from the method list and then // return the result. This would give the caller a good idea of what kind // of functions that particular workflow supports. $supported = array(); foreach ($methods as $i => $method) { if (!method_exists($this, $method)) { $supported[] = $methods[$i]; } } return $methods; }
public function regenerateSessionId() { // get dependencies. $security = \Painless::load('system/common/security'); $config = \Painless::load('system/common/config'); // get hash algorithm to use for session key generation. $hashAlgo = $config->get('session.id.hash_algo'); // Save the existing session's data. $existingSessionData = $_SESSION; session_write_close(); $newSessionId = $security->uniqueHash($hashAlgo); session_id($newSessionId); // unable to regenerate session ID. Need to re-test this soon. session_start(); // Save the existing session data back to current session. $_SESSION = $existingSessionData; return $newSessionId; }
public function sql() { if (empty(self::$queryBuilder)) { self::$queryBuilder = \Painless::load('system/data/sql/sql-factory'); } return self::$queryBuilder; }
/** * Processes the URI and returns the parameter array, as well as mapping out * module, workflow, and content type * @param array $uri the URI in an array * @return array an array of $module, $controller, $params and * $contentType */ protected function mapUri(array &$uri) { // Grab dependencies $config = \Painless::load('system/common/config'); // Localize the variables $module = ''; $controller = ''; $contentType = ''; $params = array(); $command = $uri; // Load the URI format from the routes config $routes = $config->get('routes.uri.config'); // Use the default routing if not configured (auto-routing) if (!is_array($routes)) { $routes = $this->defaultRoute; } // Process the URI list $count = count($uri); for ($i = 0; $i < $count; $i++) { // If the $uri segment is empty (most probably caused by double // backslashes - //), remove it from the array if (empty($uri[$i])) { unset($uri[$i]); continue; } if (isset($routes[$i])) { $con = $routes[$i]; if ('alias' === $con) { // Get the workflow and module mapping, and then append the // rest of the URI into the params array. No point proceeding // further as alias don't play well with module and workflow $routeMap = $config->get('routes.alias'); if (isset($routeMap[$uri[$i]])) { list($module, $controller) = $routeMap[$uri[$i]]; } // Only do this if this is not the end of the URI array if ($i !== $count) { $params = array_values(array_merge($params, array_slice($uri, $i + 1))); break; } } elseif ('module' === $con) { // Grab the module $module = $uri[$i]; } elseif ('controller' === $con) { // Grab the controller $controller = $uri[$i]; } elseif ('param' === $con) { $params[] = $uri[$i]; } } else { $params = array_values(array_merge($params, array_slice($uri, $i))); break; } } // Now, we try to determine the content type by checking the last URI // segment for a dotted notation $count = count($params); if ($count > 0) { $last = $params[$count - 1]; $pos = strpos($last, '.'); if (FALSE !== $pos) { // extract the content type from the segment $contentType = substr($last, $pos + 1); // Make sure the content type is valid if (empty($contentType)) { $contentType = 'html'; } // remove the content type from the last URI segment $params[$count - 1] = substr($last, 0, $pos); } } // Ensure that module and controller are defined. If they are not, try to // load them from the config file if (empty($module) && empty($uri[0])) { $module = $config->get('routes.uri.default.module'); } if (empty($controller) && empty($uri[0])) { $controller = $config->get('routes.uri.default.controller'); } return array($module, $controller, $params, $contentType); }
/** * Processes the request and response to compile the right output * @param Request $request a request object * @param Response $response a response object * @return mixed an output compiled by the appropriate compiler */ public function process($request, $response) { // Localize the variables $view = NULL; $method = $request->method; $module = $request->module; $controller = $request->controller; $contentType = $request->contentType; // If $module and $controller exists, find the View controller if (!empty($module) && !empty($controller)) { // Load the correct view $view = \Painless::load("view/{$module}/{$controller}"); // If the view does not exists, return a 404 if (!empty($view)) { $view->request = $request; $view->response = $response; // Get the output from the view by running the appropriate method. Once // the method has been run, it's safe to assume that $view has properly // post-processed all necessary data and payload, and that now the // compiler should have enough information to render the output if ($view->preProcess()) { $view->{$method}(); } $view->postProcess(); } } // At this point, if the view is NULL, create a default view just to // pacify the angry view compiler. if (empty($view)) { $view = \Painless::load('system/view/view', \Painless::LP_LOAD_NEW); $view->request = $request; $view->response = $response; } // Load the appropriate view compiler $compiler = \Painless::load("system/view/compiler/{$contentType}"); // If the content type is not suppoted, $compiler will be NULL. Handle // the error here if (NULL === $compiler) { // Use the default HTML compiler $compiler = \Painless::load("system/view/compiler/html"); } // Return the processed output as a response; return $compiler->process($view); }
public function destroy() { \Painless::load('system/common/session')->destroy(); $this->identity = NULL; }
/** * Loads an adapter * @param array $nsa an array of tokens from the namespace string * @param string $ns the namespace string in full * @return array the meta data on how to load the component */ protected function adapter($nsa, $ns) { // Throw an exception of $nsa does not meet the correct length req. if (count($nsa) < 2) { throw new \ErrorException('Adapter namespace should follow this format: adapter/[adapter]'); } // The second key in the $nsa array is always the module name, followed // by the dao name $adapter = $nsa[1]; // Load the base class first \Painless::load('system/data/adapter/base', \Painless::LP_DEF_ONLY); return array('extpath' => $this->appPath . 'system/data/adapter/' . $adapter . EXT, 'extname' => '\\' . dash_to_pascal($this->appName) . '\\System\\Data\\Adapter\\' . dash_to_pascal($adapter), 'basepath' => $this->corePath . 'system/data/adapter/' . $adapter . EXT, 'basename' => '\\Painless\\System\\Data\\Adapter\\' . dash_to_pascal($adapter)); }
public function execute($entry, $cmd = '', $data = array(), $role = array()) { // Here we need to determine the entry point. There are only 3 of them: // HTTP (includes REST calls), CLI (including cron jobs) and APP. The // first two are fairly self-explanatory, but APP needs more explanation // on this front. // // When a request to APP is made, Painless would automatically convert it // to either HTTP or APP. First it'll look inside the app registry, and // check the app's path. If the path starts with a http://, it'll convert // the call to a HTTP call instead, and if not, it'll assume its a file // path and use APP as is. // // Example: // Painless::request( 'GET app://flight-plan/id/123' ); // will first search for the app's path inside the registry, and // if it looks like this: // $config['apps']['flight-plan'] = '/usr/local/web/htdocs/flight-plan'; // then it is a local call, and if it looks like this: // $config['apps']['flight-plan'] = 'http://flight-plan.foo.com:8003'; // then it is a REST call. // Load the router into the Core registry $router = \Painless::load('system/common/router'); // Localize the response variable $response = FALSE; // Log the entry point, which would return a sequence number $seq = $this->log('protocol', $entry, 0); // Send the command to the router to process, which will create a request // object containing all routing information (as well as some extra info // like agent string, content type, etc) if (\Painless::RUN_HTTP === $entry || \Painless::RUN_CLI === $entry || \Painless::RUN_APP === $entry || \Painless::RUN_INTERNAL) { // Send the router the command to receive a request $request = $router->process($entry, $cmd, $data, $role); // By now $cmd is an array. Change it back to a string $cmd = implode('/', $cmd); // Set this request as the active one $this->active = $request; // Log the request $this->log('request', $request, $seq); // If $request is FALSE, something baaaaadddddd has happened inside // the router. Use a 500 error response instead of dispatching it. if (FALSE === $request) { $response = \Painless::manufacture('response', 500, 'Fatal error when trying to process the command in router. See log for more details.'); } elseif (empty($request->module)) { $response = \Painless::manufacture('response', 404, "Module not found for the command: [{$cmd}]"); } elseif (empty($request->controller)) { $response = \Painless::manufacture('response', 404, "Controller not found for the command: [{$cmd}]"); } else { $response = $router->dispatch($request); } } else { // Manufacture an empty request $request = \Painless::manufacture('request', '', '', ''); // Set this request as the active one $this->active = $request; // Log the request $this->log('request', $request); // Manufacture a 500 error status response object $response = \Painless::manufacture('response', 500, 'Invalid entry point'); } // Make sure $response is the correct type if (!$response instanceof \Painless\System\Workflow\Response) { $response = \Painless::manufacture('response', 500, 'Invalid returned response'); } // Log the response object $this->log('response', $response, $seq); // Get the renderer $render = \Painless::load('system/common/render'); // Process the request and response to get an output $response = $render->process($request, $response); // Log the response object generated by the renderer $this->log('output', $response, $seq); // Now we can safely assume that $response has all the necessary headers // and payload. We return this to the invoking agent to render it. return $response; }
public function send() { $this->init(); $config = \Painless::load('system/common/config'); $smtpServer = $config->get('email.host'); $port = $config->get('email.port'); $timeout = $config->get('email.timeout'); $mailbox = $this->mailbox; if ('' === $mailbox) { $mailbox = 'default'; } // Get the correct email mailbox profile $fromName = $config->get("email.{$mailbox}.from_name"); $fromAddress = $config->get("email.{$mailbox}.from_address"); $username = $config->get("email.{$mailbox}.username"); $password = $config->get("email.{$mailbox}.password"); // Connect to the host on the specified port $smtpConnect = fsockopen($smtpServer, $port, $errno, $errstr, $timeout); fgets($smtpConnect, 515); if (empty($smtpConnect)) { return FALSE; } $newLine = "\r\n"; // Request Auth Login fputs($smtpConnect, "AUTH LOGIN" . $newLine); fgets($smtpConnect, 515); // Send username fputs($smtpConnect, base64_encode($username) . $newLine); $ret = fgets($smtpConnect, 515); if (stripos($ret, 'error') !== FALSE) { return FALSE; } // Send password fputs($smtpConnect, base64_encode($password) . $newLine); $ret = fgets($smtpConnect, 515); if (stripos($ret, 'error') !== FALSE) { return FALSE; } // Say Hello to SMTP fputs($smtpConnect, "HELO {$smtpServer}" . $newLine); fgets($smtpConnect, 515); // Email From $from = $fromAddress; fputs($smtpConnect, "MAIL FROM: {$from}" . $newLine); fgets($smtpConnect, 515); // Email To // includes all to, cc, bcc addresses. $count = count($this->to); for ($i = 0; $i < $count; ++$i) { $toAddress = $this->to[$i]['address']; fputs($smtpConnect, "RCPT TO: {$toAddress}" . $newLine); fgets($smtpConnect, 515); } $count = count($this->cc); for ($i = 0; $i < $count; ++$i) { $ccAddress = $this->cc[$i]['address']; fputs($smtpConnect, "RCPT TO: {$ccAddress}" . $newLine); fgets($smtpConnect, 515); } $count = count($this->bcc); for ($i = 0; $i < $count; ++$i) { $bccAddress = $this->bcc[$i]['address']; fputs($smtpConnect, "RCPT TO: {$bccAddress}" . $newLine); fgets($smtpConnect, 515); } // The Email fputs($smtpConnect, "DATA" . $newLine); fgets($smtpConnect, 515); // if "text/html" is sent, send along a plain text version as well for great compatibility. if (self::HTML === $this->contentType) { $randomHash = md5(date('r', time())); $toStr = $this->generateTo(); $ccStr = $this->generateCc(); $bccStr = $this->generateBcc(); $plainTextContent = strip_tags($this->content); // TODO: need better html stripper than this $subject = $this->subject; $content = $this->content; $charset = $this->charset; // Construct Headers $headers = "MIME-Version: 1.0" . $newLine; $headers .= "Subject: {$subject}" . $newLine; $headers .= "From: {$fromName} <{$fromAddress}>" . $newLine; $headers .= "To: {$toStr}" . $newLine; $headers .= "Cc: {$ccStr}" . $newLine; $headers .= "Bcc: {$bccStr}" . $newLine; $headers .= "Content-Type: multipart/alternative; boundary={$randomHash}" . $newLine; $headers .= "--{$randomHash}" . $newLine; $headers .= "Content-Type: text/plain; charset=ISO-8859-1" . $newLine; $headers .= "{$plainTextContent}" . $newLine; $headers .= "--{$randomHash}" . $newLine; $headers .= "Content-Type: text/html; charset=\"{$charset}\"" . $newLine; $headers .= "{$content}" . $newLine; $headers .= "--{$randomHash}--" . $newLine; fputs($smtpConnect, "{$headers}.\n"); fgets($smtpConnect, 515); } else { // Construct Headers $headers = "MIME-Version: 1.0" . $newLine; $contentType = $this->contentType; $charset = $this->charset; $encoding = $this->encoding; $headers .= "Content-Type: {$contentType}; charset=\"{$charset}\"" . $newLine; $headers .= "Content-transfer-encoding: {$encoding}" . $newLine; $toStr = $this->generateTo(); $ccStr = $this->generateCc(); $bccStr = $this->generateBcc(); $subject = $this->subject; $content = $this->content; fputs($smtpConnect, "To: {$toStr}\nCc: {$ccStr}\nBcc: {$bccStr}\nFrom: {$fromName} <{$fromAddress}>\nSubject: {$subject}\n{$headers}\n{$content}\n.\n"); fgets($smtpConnect, 515); } // Say Bye to SMTP fputs($smtpConnect, "QUIT" . $newLine); fgets($smtpConnect, 515); return TRUE; }
/** * Manufactures a component using the passed in parameters * @param string $component the name of the component to be loaded * @param array $opt the loading parameters * @return object the manufactured component */ public static function manufacture() { // Get the list of arguments passed in $args = func_get_args(); // Don't continue if no component specified if (empty($args) || !is_string($args[0])) { throw new \ErrorException('You need to specify a component type to manufacture by setting it as the first argument of manufacture( ).'); } // Extract the first segment of $args as the component type $component = array_shift($args); // All clear. Create the factory and manufacture away! $factory = \Painless::load('system/common/factory'); // Don't continue if the component is not suppoted! if (!method_exists($factory, $component)) { throw new \ErrorException('Trying to manufacture a non-supported component [' . $component . ']'); } // Create the component $com = call_user_func_array(array($factory, $component), $args); // Handle errors if necessary if (FALSE === $com) { throw new \ErrorException('Unable to manufacture the component requested [' . $request . ']'); } return $com; }