function getImg() { if (isset($_GET['doodiagnostic_pic']) && file_exists(Doo::conf()->BASE_PATH . 'diagnostic/assets/' . $_GET['doodiagnostic_pic'])) { Doo::app()->setRawHeader('Content-Type: image/png'); Doo::app()->setRawHeader('Content-Length: ' . filesize(Doo::conf()->BASE_PATH . 'diagnostic/assets/' . $_GET['doodiagnostic_pic'])); ob_clean(); readfile(Doo::conf()->BASE_PATH . 'diagnostic/assets/' . $_GET['doodiagnostic_pic']); exit; } }
/** * Show all URLs available in application based on the route definition */ public static function showAllUrl() { $data = array(); $n = 1; $route = Doo::app()->route; foreach ($route as $req => $r) { foreach ($r as $rname => $value) { $rname_strip = 'index.php' . $rname; $data[$n++ . " {$req}"] = '<a href="' . Doo::conf()->APP_URL . $rname_strip . '">' . $rname . '</a>'; } } echo '<pre>'; print_r($data); }
/** * Build URL based on a route Controller and Method. * @param string $controller Name of the Controller * @param string $method Name of the Action method * @param array $param Parameter values to build the route URL * @param bool $addAppUrl Add the APP_URL to the url * @return string URL of a route */ public static function url2($controller, $method, $param = null, $addAppUrl = false) { $route = Doo::app()->route; $routename = null; foreach ($route as $req => $r) { foreach ($r as $rname => $value) { if ($value[0] == $controller && $value[1] == $method) { $routename = $rname; break; } } } if ($addAppUrl) { $routename = Doo::conf()->APP_URL . substr($routename, 1); } if ($param != null) { foreach ($param as $k => $v) { $routename = str_replace(':' . $k, $v, $routename); } } return $routename; }
<?php #Add include folder for shard-query set_include_path(get_include_path() . PATH_SEPARATOR . '../include'); #load configs include './protected/config/common.conf.php'; include './protected/config/routes.conf.php'; include './protected/config/db.conf.php'; #Just include this for production mode //include $config['BASE_PATH'].'deployment/deploy.php'; include $config['BASE_PATH'] . 'Doo.php'; include $config['BASE_PATH'] . 'app/DooConfig.php'; # Uncomment for auto loading the framework classes. spl_autoload_register('Doo::autoload'); Doo::conf()->set($config); # remove this if you wish to see the normal PHP error view. #include $config['BASE_PATH'].'diagnostic/debug.php'; # database usage //Doo::useDbReplicate(); #for db replication master-slave usage //Doo::db()->setMap($dbmap); Doo::db()->setDb($dbconfig, $config['APP_MODE']); //Doo::db()->sql_tracking = true; #for debugging/profiling purpose Doo::app()->route = $route; # Uncomment for DB profiling //Doo::logger()->beginDbProfile('doowebsite'); Doo::app()->run(); //Doo::logger()->endDbProfile('doowebsite'); //Doo::logger()->rotateFile(20); //Doo::logger()->writeDbProfiles();
/** * Reads a file and send a header to force download it. * @param string $file_str File name with absolute path to it * @param bool $isLarge If True, the large file will be read chunk by chunk into the memory. * @param string $rename Name to replace the file name that would be downloaded */ public function download($file, $isLarge = FALSE, $rename = NULL) { if ($rename == NULL) { if (strpos($file, '/') === FALSE && strpos($file, '\\') === FALSE) { $filename = $file; } else { $filename = basename($file); } } else { $filename = $rename; } Doo::app()->setRawHeader('Content-Description: File Transfer'); Doo::app()->setRawHeader('Content-Type: application/octet-stream'); Doo::app()->setRawHeader("Content-Disposition: attachment; filename=\"{$filename}\""); Doo::app()->setRawHeader('Expires: 0'); Doo::app()->setRawHeader('Cache-Control: must-revalidate, post-check=0, pre-check=0'); Doo::app()->setRawHeader('Pragma: public'); Doo::app()->setRawHeader('Content-Length: ' . filesize($file)); ob_clean(); flush(); if ($isLarge) { $this->readfile_chunked($file); } else { readfile($file); } }
/** * Build URL based on a route Controller and Method. * @param string $controller Name of the Controller * @param string $method Name of the Action method * @param array $param Parameter values to build the route URL * @param bool $addAppUrl Add the APP_URL to the url * @return string URL of a route */ public static function url2($controller, $method, $param = null, $addAppUrl = false) { $route = Doo::app()->route; $routename = null; foreach ($route as $req => $r) { if (is_array($r) === false) { continue; } foreach ($r as $rname => $value) { //normal routes if (isset($value[0]) && $value[0] == $controller && $value[1] == $method) { $routename = $rname; break; } else { if ($rname === 'catchall') { $catchallRoutes[] = $value; } } } if (!empty($routename)) { break; } } if (empty($routename) && !empty($catchallRoutes)) { // catchall routes foreach ($catchallRoutes as $value) { foreach ($value as $rname2 => $value2) { if ($value2[0] == $controller && $value2[1] == $method) { $routename = $rname2; $catchall = true; break; } } if (!empty($routename)) { break; } } } if ($addAppUrl) { $routename = Doo::conf()->APP_URL . substr($routename, 1); } if (isset($catchall)) { if ($param != null) { $totalDefinedKey = substr_count($routename, ':'); if ($totalDefinedKey > 0) { $i = 0; foreach ($param as $k => $v) { $routename = str_replace(':' . $k, $v, $routename); unset($param[$k]); $i++; if ($i === $totalDefinedKey) { break; } } } if (!empty($param)) { $routename .= '/' . implode('/', $param); } } } else { if ($param != null) { foreach ($param as $k => $v) { $routename = str_replace(':' . $k, $v, $routename); } } } return $routename; }
/** * Redirect to an external URL with HTTP 302 header sent by default * * @param string $location URL of the redirect location * @param bool $exit to end the application * @param code $code HTTP status code to be sent with the header * @param array $headerBefore Headers to be sent before header("Location: some_url_address"); * @param array $headerAfter Headers to be sent after header("Location: some_url_address"); */ public static function redirect($location, $exit = true, $code = 302, $headerBefore = NULL, $headerAfter = NULL) { if ($headerBefore !== null) { foreach ($headerBefore as $h) { Doo::app()->setRawHeader($h); } } Doo::app()->setRawHeader("Location: {$location}", true, $code); if ($headerAfter !== null) { foreach ($headerAfter as $h) { Doo::app()->setRawHeader($h); } } if ($exit) { exit; } }
public function outputJSON($result) { Doo::app()->setRawHeader('Cache-Control: no-cache, must-revalidate'); Doo::app()->setRawHeader('Expires: Mon, 26 Jul 1970 05:00:00 GMT'); Doo::app()->setRawHeader('Content-type: application/json'); echo json_encode($result); }
/** * Set raw header. eg. 'HTTP/1.1 200 OK' * @param string $rawHeader Header content * @param bool $replace Whether to replace the same header that is previously set * @param int $code HTTP status code */ public function setRawHeader($rawHeader, $replace = true, $code = null) { Doo::app()->setRawHeader($rawHeader, $replace, $code); }
protected function displayMultiSelectMenu($question, $options, $clearScreenBeforeDisplay = false, $clearScreenAfterDisplay = false) { if ($clearScreenBeforeDisplay) { $this->clearScreen(); } // If we are displaying numerical option keys convert options and store the old keys for later $origKeys = array(); // We let user make multiple selections using numerical references $i = 0; $temp = array(); foreach ($options as $key => $value) { $temp[$i] = $value; $origKeys[$i] = $key; $i++; } $options = $temp; // Display the menu options $this->writeLine($question); foreach ($options as $key => $answer) { $this->writeLine(" {$key}) {$answer}"); } $this->write("Please select an option(s): "); // Get the users choice $choices = array(); $allPass = false; $commands = array_keys($options); do { if (!empty($choices)) { $this->write("\nUnknown or Invalid Option(s). Please select another option(s): "); } $choices = explode(',', trim(fgets(Doo::app()->streamStdIn))); $allPass = true; foreach ($choices as $choice) { $allPass = $allPass && in_array($choice, $commands); } } while (empty($choices) || $allPass == false); if ($clearScreenAfterDisplay) { $this->clearScreen(); } $selection = array(); foreach ($choices as $choice) { $selection[] = $origKeys[$choice]; } return $selection; }
/** * Handles auto routing. * * <p>If AUTOROUTE is on, you can access a controller action method by * accessing the URL http://localhost/controllername/methodname</p> * * <p>If your controller class has a Camel Case naming convention for the class name, * access it through http://localhost/camel-case/method for a class name CamelCaseController</p> * * <p>If no method is specified in the URL, <i>index()</i> will be executed by default if available. * If no matching controller/method is found, a 404 status will be sent in the header.</p> * * <p>The returned parameter list is access through an indexed array ( $param[0], $param[1], $param[2] ) instead of a assoc array in the Controller class.</p> * * @param string $subfolder Relative path of the sub directory where the app is located. eg. http://localhost/doophp, the value should be '/doophp/' * @return array returns an array consist of the Controller class, action method and parameters of the route */ public function auto_connect($subfolder = '/', $autoroute_alias = null) { $uri = $_SERVER['REQUEST_URI']; //remove Subfolder from the URI if exist if ($subfolder != '/') { $uri = substr($uri, strlen($subfolder)); } //remove index.php/ from the URI if exist if (strpos($uri, 'index.php/') === 0) { $uri = substr($uri, strlen('index.php/')); } //strip out the GET variable part if start with /? if ($pos = strpos($uri, '/?')) { $uri = substr($uri, 0, $pos); } else { if ($pos = strpos($uri, '?')) { $tmp = explode('?', $uri); $uri = $tmp[0]; } } if ($uri !== '/') { $end = strlen($uri) - 1; while ($end > 0 && $uri[$end] === '/') { $end--; } $uri = substr($uri, 0, $end + 1); } //remove the / in the first char in REQUEST URI if ($uri[0] === '/') { $uri = substr($uri, 1); } //spilt out GET variable first $uri = explode('/', $uri); $module = null; if (isset(Doo::conf()->MODULES) === true) { if (in_array($uri[0], Doo::conf()->MODULES) === true) { $module = $uri[0]; array_shift($uri); } else { if (empty(Doo::app()->route['autoroute_force_dash']) === false) { $moduleRemUnderscore = explode("\t", str_replace('_', '-', implode("\t", Doo::conf()->MODULES))); if (in_array($uri[0], $moduleRemUnderscore) === true) { $module = $uri[0]; array_shift($uri); } } } } //if controller and method not found. if (isset($uri[0]) === false) { return; } $controller_name = $uri[0]; Doo::conf()->AUTO_VIEW_RENDER_PATH = array($controller_name); //controller name can't start with a -, and it can't have more than 1 - if (strpos($controller_name, '-') === 0 || strpos($controller_name, '--') !== false) { return; } //if - detected, make controller name camelcase if (strpos($controller_name, '-') !== false) { $controller_name = str_replace(' ', '', ucwords(str_replace('-', ' ', $controller_name))); } $controller_name = ucfirst($controller_name); $controller_name .= 'Controller'; //if method is in uri, replace - to camelCase. else method is empty, make it access index if (empty($uri[1]) === false) { $method_name = $method_name_ori = $uri[1]; //controller name can't start with a -, and it can't have more than 1 - if (strpos($method_name, '-') === 0 || strpos($method_name, '--') !== false) { return; } //if - detected, make method name camelcase if (strpos($method_name, '-') !== false) { //$method_name = lcfirst( str_replace(' ', '', ucwords( str_replace('-', ' ', $method_name) ) ) ); $method_name = str_replace(' ', '', ucwords(str_replace('-', ' ', $method_name))); $method_name[0] = strtolower($method_name[0]); } Doo::conf()->AUTO_VIEW_RENDER_PATH[] = $uri[1]; } else { $method_name = $method_name_ori = 'index'; Doo::conf()->AUTO_VIEW_RENDER_PATH[] = 'index'; } //the first 2 would be Controller and Method, the others will be params if available, access through Array arr[0], arr[1], arr[3] $params = null; if (sizeof($uri) > 2) { $params = array_slice($uri, 2); } //match alias for autoroutes if ($autoroute_alias !== null) { $alias = '/' . urldecode($uri[0]); if (isset($autoroute_alias[$alias]) === true) { $convertname = $controller_name = $autoroute_alias[$alias]; //if alias defined as array('controller'=>'TestController', 'module'=>'example') if (is_array($convertname) === true) { $controller_name = $controller_name['controller']; if (isset($convertname['module']) === true) { $module = $convertname['module']; } $convertname = $controller_name; } //camel case to dash for controller $convertname[0] = strtolower($convertname[0]); Doo::conf()->AUTO_VIEW_RENDER_PATH[0] = strtolower(preg_replace('/([A-Z])/', '-$1', substr($convertname, 0, -10))); } else { $uridecode = urldecode(implode('/', $uri)); $aliaskey = array_keys($autoroute_alias); //escape string and convert to regex pattern to match with URI, (alias1|alias 2|alias3\/alias3_2) $aliaskey = str_replace("\t", '|', preg_quote(implode("\t", $aliaskey), '/')); //use regex to eliminate looping through the list of alias keys if (preg_match('/^(' . $aliaskey . ')\\//', '/' . $uridecode . '/', $matchedKey) > 0) { //key of the matched autoroute alias $r = $matchedKey[1]; $convertname = $controller_name = $autoroute_alias[$r]; //if alias defined as array('controller'=>'TestController', 'module'=>'example') if (is_array($convertname) === true) { $controller_name = $controller_name['controller']; if (isset($convertname['module']) === true) { $module = $convertname['module']; } $convertname = $controller_name; } //camel case to dash for controller $convertname[0] = strtolower($convertname[0]); Doo::conf()->AUTO_VIEW_RENDER_PATH[0] = strtolower(preg_replace('/([A-Z])/', '-$1', substr($convertname, 0, -10))); //explode and parse the method name + parameters $uridecode = explode('/', substr($uridecode, strlen($r))); $method_name = $method_name_ori = $uridecode[0]; if (empty($method_name) === true) { $method_name = $method_name_ori = 'index'; } else { if (sizeof($uridecode) > 1) { $params = array_slice($uridecode, 1); } else { $params = null; } //controller name can't start with a -, and it can't have more than 1 - if (strpos($method_name, '-') === 0 || strpos($method_name, '--') !== false) { return; } //if - detected, make method name camelcase if (strpos($method_name, '-') !== false) { //$method_name = lcfirst( str_replace(' ', '', ucwords( str_replace('-', ' ', $method_name) ) ) ); $method_name = str_replace(' ', '', ucwords(str_replace('-', ' ', $method_name))); $method_name[0] = strtolower($method_name[0]); } } Doo::conf()->AUTO_VIEW_RENDER_PATH[1] = $method_name; } } } return array($controller_name, $method_name, $method_name_ori, $params, $module); }
/** * Authenticate using a function/method to process the auth logic. You can use this method to authenticate against a database data. * For HTTP digest auth, password key in by the user in the login dialog cannot be retrieved in plain text. * Thus, storing of hased password is required, eg.: * <code> * //Hash format * md5($username .':'. $realm .':'. $password) * * //Or use this method to generate the hash * DooDigestAuth::hashPassphrase($username, $password, $realm); * </code> * * Example usage to authenticate with a database: * First, store the hash in a table. * <code> * // after creating a user, store this * // Table: user_realm_hash, Model: UserRealmHash * // columns: username, realm, hash, user_id * $realmHash = new UserRealmHash(); * $realmHash->username = '******'; * $realmHash->realm = 'Admin Section'; * $realmHash->hash = DooDigestAuth::hashPassphrase('admin', 'password', 'Admin Section'); * $realmHash->insert(); * </code> * * To begin the authentication process, put this line in your controller/method where you need to authenticate the user * <code> * // use $this->authUser * class AdminController extends DooController { * public function manageAll(){ * DooDigestAuth::authWithFunc('Admin Login', array($this, 'authUser'), 'Login Failed!', null, true); * //... CRUD code follows ... * } * * public function authUser( $username, $realm ){ * $u = new UserRealmHash(); * $u->realm = $realm; * $u->username = $username; * $u = $u->getOne(); * if($u){ * return $u->hash; * } * return null; * } * </code> * * <p>HTTP Digest Authentication doesn't work with PHP in CGI mode, * you have to add this into your .htaccess <code>RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]</code></p> * * @param string $realm Name of the authentication session * @param array $func Function/method to process the authentication. Pass the function name(string) or an array of the object and its method name. The function should accept 2 parameteres (username & realm), and should return the matching password string or null to deny the user. * @param string $failMsg Message to be displayed if the User cancel the login * @param string $failURL URL to be redirect if the User cancel the login * @param boolean $passwordHashed Use hashed password to authenticate. * @return string The username if login success. */ public static function authWithFunc($realm, $func, $failMsg = NULL, $failURL = NULL, $passwordHashed = false) { if (!empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && strpos($_SERVER['REDIRECT_HTTP_AUTHORIZATION'], 'Digest') === 0) { $_SERVER['PHP_AUTH_DIGEST'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION']; } if (empty($_SERVER['PHP_AUTH_DIGEST'])) { Doo::app()->setRawHeader('WWW-Authenticate: Digest realm="' . $realm . '",qop="auth",nonce="' . uniqid() . '",opaque="' . md5($realm) . '"'); Doo::app()->setRawHeader('HTTP/1.1 401 Unauthorized'); if ($failMsg != NULL) { die($failMsg); } if ($failURL != NULL) { die("<script>window.location.href = '{$failURL}'</script>"); } exit; } $data = self::httpDigestParse($_SERVER['PHP_AUTH_DIGEST']); if (is_string($func)) { $hashedPassword = $func($data['username'], $realm); } else { $hashedPassword = $func[0]->{$func[1]}($data['username'], $realm); } // analyze the PHP_AUTH_DIGEST variable if (!$data || !isset($hashedPassword)) { Doo::app()->setRawHeader('WWW-Authenticate: Digest realm="' . $realm . '",qop="auth",nonce="' . uniqid() . '",opaque="' . md5($realm) . '"'); Doo::app()->setRawHeader('HTTP/1.1 401 Unauthorized'); if ($failMsg != NULL) { die($failMsg); } if ($failURL != NULL) { die("<script>window.location.href = '{$failURL}'</script>"); } exit; } // generate the valid response if ($passwordHashed) { $A1 = $hashedPassword; } else { $A1 = md5($data['username'] . ':' . self::getRealm($realm) . ':' . $hashedPassword); } $A2 = md5($_SERVER['REQUEST_METHOD'] . ':' . $data['uri']); $valid_response = md5($A1 . ':' . $data['nonce'] . ':' . $data['nc'] . ':' . $data['cnonce'] . ':' . $data['qop'] . ':' . $A2); if ($data['response'] != $valid_response) { Doo::app()->setRawHeader('HTTP/1.1 401 Unauthorized'); Doo::app()->setRawHeader('WWW-Authenticate: Digest realm="' . $realm . '",qop="auth",nonce="' . uniqid() . '",opaque="' . md5($realm) . '"'); if ($failMsg != NULL) { die($failMsg); } if ($failURL != NULL) { die("<script>window.location.href = '{$failURL}'</script>"); } exit; } // ok, valid username & password return $data['username']; }