* @license PHP License * @package WB * @subpackage db */ /** * Simple table access * * @version 0.2.0 * @package WB * @subpackage db */ class WBDatasource_ObscureCode extends WBStdClass { /** * tble object * @var WBDatasource_Table */ protected $table; /** * current code * @var string */ protected $code = null; /** * prepared clause * @var array */ protected $clause = array( array( 'field' => 'namespace', 'value' => '', ), array( 'field' => 'xid', 'value' => '', ) ); /** * craete table object * * @param array $parameter */ public function __construct($parameter = array()) { $this->table = WBClass::create('WBDatasource_Table'); } /** * set namespace string * * @param string $ns * @return WBDatasource_ObscureCode */ public function setNamespace($ns) { if ($this->clause[0]['value'] == $ns) { return $this; } $this->clause[0]['value'] = $ns; $this->code = null; return $this; } /** * set id * * @param string $id * @return WBDatasource_ObscureCode */ public function setId($id) { if ($this->clause[1]['value'] == $id) { return $this; } $this->clause[1]['value'] = $id; $this->code = null; return $this; } /** * create a random obscure code * * Make an alphanumeric random string to be used to obscure ids. * Be careful, those obscure codes are case sensitive. Hence one * actually can't compare it using WHERE clause for case insensive * table (which is pretty much defualt). Therefore, use an additional * (numeric) primary key to load record from databse and compare * the obscure code wwith PHP's strink functions. * * @param int $length length between 2 and 255 * @param bool $startLetter fist character will be a letter * @param bool $endLetter last character will be a letter * @param bool $capitalOnly use only capital letters * @return string */ static public function mkRandObscure($length = 8, $startLetter = false, $endLetter = false, $capitalOnly = false) { if ($length > 255) { $length = 255; } if ($length < 2) { $length = 2; } // avoid confusing letters like 0 and O $alpha = range('2', '9'); $cntN = count($alpha); $alpha = array_merge($alpha, array( 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' //, 'I' , 'J', 'K', 'L', 'M', 'N' //, 'O' , 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' )); if (!$capitalOnly) { $alpha = array_merge($alpha, array( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' , 'i', 'j' //, 'l' , 'm', 'n' //, 'o' , 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' )); } $cnt = count($alpha) - 1; $rc = array(); // force obscurce code to start with a letter if ($startLetter) { $rc[] = $alpha[rand($cntN, $cnt)]; --$length; } if ($endLetter) { --$length; } // fill with random letters and digists for ($i = 0; $i < $length; ++$i) { $rc[] = $alpha[rand(0, $cnt)]; } if ($endLetter) { $rc[] = $alpha[rand($cntN, $cnt)]; } return implode('', $rc); } /** * create obscure code * * Create random string using a-z and 0-9. Random string may be up * to 255 characters long. Also random string always starts and ends * with a letter! * * @param int $length * @return WBDatasource_ObscureCode */ public function create($length = 8) { $this->clear(); $this->code = self::mkRandObscure($length, true, true); $save = array( 'namespace' => $this->clause[0]['value'], 'xid' => $this->clause[1]['value'], 'code' => $this->code ); $this->table->save('obscurecode', '__new', $save); return $this; } /** * clrear random code * * remove random code from database * * @return WBDatasource_ObscureCode */ public function clear() { $this->code = null; $this->table->delete('obscurecode', null, null, $this->clause); return $this; } /** * receive current obscure code * * @return string */ public function get() { if ($this->code) { return $this->code; } $list = $this->table->get('obscurecode', null, null, $this->clause); if (count($list) != 1) { return ''; } $this->code = $list[0]['code']; return $this->code; } /** * verify string against obscure code * * see whether current code matches * * @param string $rc * @param bool $once if true, clear code after check * @return bool true if codes are the same */ public function check($code, $once = false) { if (empty($code)) { return false; } $current = $this->get(); if ($once) { $this->clear(); } if ($current == $code) { return true; } return false; } }