├── .gitignore ├── .htaccess ├── webdata ├── models │ ├── README │ ├── UnitData.php │ ├── CompanyGraph.php │ ├── KeyValue.php │ ├── ColumnGroup.php │ └── Unit.php ├── prompt.php ├── stdlibs │ └── pixframework │ │ ├── coverage │ │ ├── glass.png │ │ ├── snow.png │ │ ├── butter.png │ │ ├── chameleon.png │ │ ├── close12_1.gif │ │ ├── scarlet_red.png │ │ ├── Array_Filter.html │ │ ├── Table_Search.html │ │ ├── Table_Db_Adapter_PDO.html │ │ └── Cache.html │ │ ├── README │ │ ├── example │ │ ├── init.inc.php │ │ ├── prompt.php │ │ ├── array │ │ │ ├── basic.php │ │ │ └── order.php │ │ ├── cache │ │ │ └── example.php │ │ └── table │ │ │ ├── models │ │ │ ├── User.php │ │ │ └── Article.php │ │ │ └── example1.php │ │ ├── Pix │ │ ├── Table │ │ │ ├── Db │ │ │ │ ├── Adapter.php │ │ │ │ └── Adapter │ │ │ │ │ ├── MsSQL │ │ │ │ │ └── Result.php │ │ │ │ │ ├── PDO │ │ │ │ │ └── Result.php │ │ │ │ │ ├── Abstract.php │ │ │ │ │ ├── Mysqli.php │ │ │ │ │ └── PixCache.php │ │ │ ├── NoThisColumnException.php │ │ │ ├── Exception.php │ │ │ ├── Row │ │ │ │ ├── Stop.php │ │ │ │ └── InvalidFormatException.php │ │ │ ├── TableNotFoundException.php │ │ │ ├── Search │ │ │ │ ├── Exception.php │ │ │ │ └── Term.php │ │ │ ├── DuplicateException.php │ │ │ ├── DataTooLongException.php │ │ │ ├── Helper │ │ │ │ ├── CacheTime.php │ │ │ │ └── EAV.php │ │ │ ├── Db.php │ │ │ └── Search.php │ │ ├── Array │ │ │ ├── Filter.php │ │ │ ├── Exception.php │ │ │ ├── Filter │ │ │ │ └── Row.php │ │ │ ├── Volume.php │ │ │ ├── Volume │ │ │ │ ├── Row.php │ │ │ │ └── ResultSet.php │ │ │ ├── Volumable.php │ │ │ ├── Array.php │ │ │ └── Merger.php │ │ ├── Helper │ │ │ ├── Exception.php │ │ │ └── Manager.php │ │ ├── Controller │ │ │ ├── NoViewException.php │ │ │ ├── Dispatcher │ │ │ │ ├── Exception.php │ │ │ │ └── Default.php │ │ │ ├── Dispatcher.php │ │ │ ├── DefaultErrorController.php │ │ │ ├── Helper │ │ │ │ ├── Alert │ │ │ │ │ └── alert.phtml │ │ │ │ ├── Alert.php │ │ │ │ ├── Json.php │ │ │ │ └── Http.php │ │ │ └── DefaultErrorController │ │ │ │ └── views │ │ │ │ └── error │ │ │ │ └── error.phtml │ │ ├── Partial │ │ │ ├── NoRender.php │ │ │ ├── BreakRender.php │ │ │ └── Helper │ │ │ │ ├── Capture.php │ │ │ │ ├── Html.php │ │ │ │ └── JQueryTmpl.php │ │ ├── Exception.php │ │ ├── Setting.php │ │ ├── HttpResponse.php │ │ ├── Session │ │ │ ├── Adapter │ │ │ │ ├── Default.php │ │ │ │ └── Cookie.php │ │ │ └── Adapter.php │ │ ├── Loader.php │ │ ├── Cache │ │ │ ├── Adapter │ │ │ │ ├── BlackHole.php │ │ │ │ ├── HandlerSocket.php │ │ │ │ ├── Memcached.php │ │ │ │ ├── Memcache.php │ │ │ │ └── Array.php │ │ │ └── Adapter.php │ │ ├── Helper.php │ │ ├── Cache.php │ │ ├── Session.php │ │ └── Array.php │ │ ├── tests │ │ ├── init.inc.php │ │ └── Pix │ │ │ ├── Helper │ │ │ ├── AllTests.php │ │ │ └── HelperTest.php │ │ │ ├── Array │ │ │ ├── AllTests.php │ │ │ └── MergerTest.php │ │ │ └── Table │ │ │ ├── AllTests.php │ │ │ ├── TableTermTest.php │ │ │ ├── TableIndexTest.php │ │ │ ├── TableCacheTest.php │ │ │ ├── TableHelperTest.php │ │ │ └── SearchTest.php │ │ └── phpunit.xml.dist ├── config.sample.php ├── scripts │ ├── init-db.php │ ├── import.php │ └── update-data.php ├── controllers │ ├── ErrorController.php │ └── IndexController.php ├── init.inc.php └── views │ └── index │ ├── about.phtml │ └── index.phtml ├── route.php ├── index.php ├── static └── build.css └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | config.php 2 | .*.swp 3 | -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | RewriteEngine on 2 | RewriteBase / 3 | RewriteRule static/ - [L] 4 | RewriteRule .* index.php 5 | -------------------------------------------------------------------------------- /webdata/models/README: -------------------------------------------------------------------------------- 1 | 台灣公司關係圖 2 | ============== 3 | 4 | * 網站位置: http://company-graph.g0v.ronny.tw/ 5 | * 程式以 BSD License 授權 6 | 7 | -------------------------------------------------------------------------------- /webdata/prompt.php: -------------------------------------------------------------------------------- 1 | createTable(); 11 | } 12 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | limit(3) as $num) { 11 | echo $num . PHP_EOL; 12 | } 13 | echo "===" . PHP_EOL; 14 | 15 | // 得到 5 6 16 | foreach ($array->offset(5)->limit(2) as $num) { 17 | echo $num . PHP_EOL; 18 | } 19 | -------------------------------------------------------------------------------- /webdata/controllers/ErrorController.php: -------------------------------------------------------------------------------- 1 | view->exception instanceof Pix_Controller_Dispatcher_Exception) { 8 | echo '404'; 9 | return $this->noview(); 10 | } else { 11 | trigger_error(strval($this->view->exception), E_USER_WARNING); 12 | return $this->noview(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Controller/Dispatcher.php: -------------------------------------------------------------------------------- 1 | errorcode = $errorcode; 19 | $this->options = $options; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Controller/DefaultErrorController.php: -------------------------------------------------------------------------------- 1 | view->exception->getMessage()}.", E_USER_WARNING); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Controller/Helper/Alert/alert.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 |

escape($this->message) ?>

12 | If you are not redirected to escape($this->url) ?>, click Here 13 | 14 | 15 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/example/cache/example.php: -------------------------------------------------------------------------------- 1 | array( 14 | array('host' => 'memcache-server-name', 'port' => 11211), 15 | ), 16 | )); 17 | 18 | $cache = new Pix_Cache(); 19 | $cache->save('test-key', 'value'); 20 | echo $cache->load('test-key'); 21 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Table/Row/InvalidFormatException.php: -------------------------------------------------------------------------------- 1 | getTableClass() . '的欄位 ' . $name. ' 格式不正確'); 18 | 19 | $this->column = $column; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/example/table/models/User.php: -------------------------------------------------------------------------------- 1 | _name = 'user'; 8 | 9 | $this->_primary = 'id'; 10 | 11 | $this->_columns['id'] = array('type' => 'int', 'auto_increment' => true); 12 | $this->_columns['name'] = array('type' => 'char', 'size' => 32); 13 | $this->_columns['password'] = array('type' => 'char', 'size' => 32); 14 | 15 | $this->_indexes['name'] = array('type' => 'unique', 'columns' => array('name')); 16 | 17 | $this->_relations['articles'] = array('rel' => 'has_many', 'type' => 'Article', 'foreign_key' => 'user_id'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/example/table/models/Article.php: -------------------------------------------------------------------------------- 1 | _name = 'article'; 8 | 9 | $this->_primary = 'id'; 10 | 11 | $this->_columns['id'] = array('type' => 'int', 'auto_increment' => true); 12 | $this->_columns['user_id'] = array('type' => 'int'); 13 | $this->_columns['post_at'] = array('type' => 'int'); 14 | $this->_columns['title'] = array('type' => 'text'); 15 | $this->_columns['body'] = array('type' => 'text'); 16 | 17 | $this->_indexes['userid_postat'] = array('type' => 'unique', 'columns' => array('user_id', 'post_at')); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /static/build.css: -------------------------------------------------------------------------------- 1 | .insights-tooltip { 2 | font-family: "proxima-nova",sans-serif; 3 | padding: 12px; 4 | color:#FFF; 5 | font-size:13px; 6 | background-color:#757575; 7 | border-radius:5px; 8 | -moz-border-radius:5px; 9 | -webkit-border-radius:5px; 10 | box-shadow:0 1px 2px rgba(0,0,0,.65),0 -1px 2px rgba(0,0,0,.65) inset; 11 | text-shadow:0 1px 1px rgba(0,0,0,.8); 12 | } 13 | 14 | .insights-graph .link { 15 | fill: none; 16 | stroke: #666; 17 | } 18 | 19 | .insights-graph .node circle { 20 | fill: #ccc; 21 | stroke: #fff; 22 | stroke-width: 1.5px; 23 | cursor:pointer; 24 | } 25 | 26 | .insights-graph text { 27 | fill: #444; 28 | font: 9px sans-serif; 29 | pointer-events: none; 30 | text-shadow: -1px 0px 3px white, -1px 0px 9px white; 31 | } -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Array/Volume.php: -------------------------------------------------------------------------------- 1 | $chunk, 'simple_mode' => true)); 20 | } 21 | 22 | static public function volume($array, $options = array()) 23 | { 24 | return new Pix_Array_Volume_ResultSet($array, $options); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /webdata/controllers/IndexController.php: -------------------------------------------------------------------------------- 1 | view->id = ($_GET['id']); 8 | if (preg_match('#^[0-9]+$#', $this->view->id)) { 9 | $unit = Unit::find(intval($this->view->id)); 10 | if (!$unit) { 11 | return $this->alert("找不到統一編號 {$this->view->id} 的公司", '/'); 12 | } 13 | $this->view->unit_title = $unit->get('公司名稱')->value; 14 | } else { 15 | $this->view->unit_title = strval($this->view->id); 16 | } 17 | } 18 | 19 | public function jsonAction() 20 | { 21 | return $this->json(GraphLib::getJSONFromID(strval($_GET['id']))); 22 | } 23 | 24 | public function aboutAction() 25 | { 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /webdata/models/UnitData.php: -------------------------------------------------------------------------------- 1 | value)) { 9 | $this->value = json_encode(json_decode($this->value)); 10 | } 11 | } 12 | } 13 | 14 | class UnitData extends Pix_Table 15 | { 16 | public function init() 17 | { 18 | $this->_name = 'unit_data'; 19 | $this->_primary = array('id', 'column_id'); 20 | $this->_rowClass = 'UnitDataRow'; 21 | 22 | $this->_columns['id'] = array('type' => 'int'); 23 | $this->_columns['column_id'] = array('type' => 'tinyint'); 24 | $this->_columns['value'] = array('type' => 'text'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | tests 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | Pix 20 | 21 | 22 | tests 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /webdata/models/CompanyGraph.php: -------------------------------------------------------------------------------- 1 | _name = 'company_graph'; 8 | $this->_primary = array('company_id', 'board_type', 'board_id'); 9 | 10 | $this->_columns['company_id'] = array('type' => 'int'); 11 | // 0 - board_id 是統一編號, 1 - board_id 是公司名稱的 crc32, 並且會在 board_name 記錄公司 12 | $this->_columns['board_type'] = array('type' => 'tinyint'); 13 | $this->_columns['board_id'] = array('type' => 'int', 'unsigned' => true); 14 | $this->_columns['board_name'] = array('type' => 'varchar', 'size' => 64); 15 | // 擁有股份 16 | $this->_columns['amount'] = array('type' => 'bigint'); 17 | 18 | $this->addIndex('board_company', array('board_type', 'board_id', 'company_id'), 'unique'); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /webdata/models/KeyValue.php: -------------------------------------------------------------------------------- 1 | _name = 'key_value'; 8 | $this->_primary = 'key'; 9 | 10 | $this->_columns['key'] = array('type' => 'char', 'size' => 32); 11 | $this->_columns['value'] = array('type' => 'text'); 12 | } 13 | 14 | public static function get($key) 15 | { 16 | return KeyValue::find(strval($key))->value; 17 | } 18 | 19 | public static function set($key, $value) 20 | { 21 | try { 22 | KeyValue::insert(array( 23 | 'key' => $key, 24 | 'value' => $value, 25 | )); 26 | } catch (Pix_Table_DuplicateException $e) { 27 | KeyValue::search(array('key' => $key))->update(array('value' => $value)); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/example/table/example1.php: -------------------------------------------------------------------------------- 1 | 'alice', 24 | 'password' => crc32('foo'), 25 | )); 26 | 27 | echo '新增一篇文章' . PHP_EOL; 28 | $article = $user_alice->create_articles(array( 29 | 'post_at' => time(), 30 | 'title' => '我是標題', 31 | 'body' => '我是內容', 32 | )); 33 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Table/Db/Adapter/MsSQL/Result.php: -------------------------------------------------------------------------------- 1 | _res = $res; 15 | } 16 | 17 | public function fetch_assoc() 18 | { 19 | return mssql_fetch_assoc($this->_res); 20 | } 21 | 22 | public function fetch_array() 23 | { 24 | return mssql_fetch_array($this->_res); 25 | } 26 | 27 | public function fetch_object() 28 | { 29 | return mssql_fetch_object($this->_res); 30 | } 31 | 32 | public function free_result() 33 | { 34 | return mssql_free_result($this->_res); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Array/Volume/Row.php: -------------------------------------------------------------------------------- 1 | _row = $row; 18 | $this->_array = $array; 19 | } 20 | 21 | public function getRow() 22 | { 23 | return $this->_row; 24 | } 25 | 26 | public function getPos() 27 | { 28 | return $this->_array->getPos($this); 29 | } 30 | 31 | public function getOrder() 32 | { 33 | return $this->_array->getOrder($this); 34 | } 35 | 36 | public function ok() 37 | { 38 | return $this->_array->rowOk($this); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Table/Db/Adapter/PDO/Result.php: -------------------------------------------------------------------------------- 1 | _res = $res; 15 | } 16 | 17 | public function fetch_assoc() 18 | { 19 | $ret = $this->_res->fetch(PDO::FETCH_ASSOC); 20 | return $ret; 21 | } 22 | 23 | public function fetch_array() 24 | { 25 | $ret = $this->_res->fetch(PDO::FETCH_NUM); 26 | return $ret; 27 | } 28 | 29 | public function fetch_object() 30 | { 31 | return $this->_res->fetch(PDO::FETCH_OBJ); 32 | } 33 | 34 | public function free_result() 35 | { 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Partial/Helper/Capture.php: -------------------------------------------------------------------------------- 1 | _capture_data[$name] = ob_get_clean(); 20 | } 21 | 22 | public function captureAppend($partial, $name) 23 | { 24 | if (!isset($this->_capture_data[$name])) { 25 | $this->_capture_data[$name] = ''; 26 | } 27 | $this->_capture_data[$name] .= ob_get_clean(); 28 | } 29 | 30 | public function getCapture($partial, $name) 31 | { 32 | return $this->_capture_data[$name]; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Controller/Helper/Alert.php: -------------------------------------------------------------------------------- 1 | partial('alert.phtml', array('message' => $message, 'url' => $url)); 30 | return $controller->noview(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /webdata/scripts/import.php: -------------------------------------------------------------------------------- 1 | intval($company_id), 20 | 'board_type' => ('name' == $board_type) ? 1 : 0, 21 | 'board_id' => ('name' == $board_type) ? crc32($board_value) : $board_value, 22 | 'board_name' => ('name' == $board_type) ? $board_nme : '', 23 | 'amount' => intval(str_replace(',', '', $amount)), 24 | )); 25 | } catch (Pix_Table_DuplicateException $e) { 26 | } 27 | } 28 | } 29 | } 30 | 31 | $i = new Importer; 32 | $i->main($_SERVER['argv'][1]); 33 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Setting.php: -------------------------------------------------------------------------------- 1 | addTestSuite('Pix_Helper_HelperTest'); 35 | 36 | return $suite; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Table/Db/Adapter/Abstract.php: -------------------------------------------------------------------------------- 1 | getSupportFeatures()); 16 | } 17 | 18 | public function getSupportFeatures() 19 | { 20 | return array(); 21 | } 22 | 23 | /** 24 | * insert multiple rows 25 | * 26 | * @param Pix_Table $table 27 | * @param array $keys columns 28 | * @param array $values_list values list 29 | * @param array $options options 30 | * @access public 31 | * @return void 32 | */ 33 | public function bulkInsert($table, $keys, $values_list, $options = array()) 34 | { 35 | foreach ($values_list as $values) { 36 | $this->insertOne($table, array_combine($keys, $values)); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/HttpResponse.php: -------------------------------------------------------------------------------- 1 | addTestSuite('Pix_Array_ArrayTest'); 35 | $suite->addTestSuite('Pix_Array_MergerTest'); 36 | 37 | return $suite; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Loader.php: -------------------------------------------------------------------------------- 1 | _options = is_array($options) ? $options : array(); 18 | } 19 | 20 | protected function getOption($key) 21 | { 22 | if (!array_key_exists($key, $this->_options)) { 23 | return null; 24 | } 25 | 26 | return $this->_options[$key]; 27 | } 28 | 29 | /** 30 | * hasOption 31 | * 32 | * @param string $key 33 | * @access protected 34 | * @return boolean 35 | */ 36 | protected function hasOption($key) 37 | { 38 | return array_key_exists($key, $this->_options); 39 | } 40 | 41 | /** 42 | * setOption 43 | * 44 | * @param string $key 45 | * @param mixed $value 46 | * @access protected 47 | * @return void 48 | */ 49 | protected function setOption($key, $value) 50 | { 51 | $this->_options[$key] = $value; 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/example/array/order.php: -------------------------------------------------------------------------------- 1 | 'alice', 9 | 'height' => 158, 10 | 'weight' => 42, 11 | 'money' => 200, 12 | ), 13 | array( 14 | 'name' => 'bob', 15 | 'height' => 182, 16 | 'weight' => 72, 17 | 'money' => 150, 18 | ), 19 | array( 20 | 'name' => 'carol', 21 | 'height' => 170, 22 | 'weight' => 58, 23 | 'money' => 200, 24 | ), 25 | ); 26 | 27 | $members = Pix_Array::factory($members); 28 | 29 | // 照身高排序 bob(182), carol(170), alice(158) 30 | foreach ($members->order('height DESC') as $member) { 31 | echo $member['name'] . '(' . $member['height'] . ')' . PHP_EOL; 32 | } 33 | echo "===" . PHP_EOL; 34 | 35 | // 照體重排序 alice(42), carol(58), bob(72) 36 | foreach ($members->order('weight ASC') as $member) { 37 | echo $member['name'] . '(' . $member['weight'] . ')' . PHP_EOL; 38 | } 39 | echo "===" . PHP_EOL; 40 | 41 | // 照錢以及身高排序 carol(200,170), alice(200,158), bob(150,182) 42 | foreach ($members->order('money DESC, height DESC') as $member) { 43 | echo $member['name'] . '(' . $member['money'] . ',' . $member['height'] . ')' . PHP_EOL; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /webdata/models/ColumnGroup.php: -------------------------------------------------------------------------------- 1 | _name = 'columngroup'; 8 | $this->_primary = 'id'; 9 | 10 | $this->_columns['id'] = array('type' => 'int', 'auto_increment' => true); 11 | $this->_columns['name'] = array('type' => 'varchar', 'size' => 32); 12 | 13 | $this->addIndex('name', array('name'), 'unique'); 14 | } 15 | 16 | protected static $_column_groups = null; 17 | protected static $_column_names = null; 18 | 19 | public static function getColumnName($id) 20 | { 21 | if (is_null(self::$_column_names)) { 22 | self::$_column_names = ColumnGroup::search(1)->toArray('name'); 23 | } 24 | return self::$_column_names[$id]; 25 | } 26 | 27 | public static function getColumnId($name) 28 | { 29 | $name = trim($name); 30 | if (is_null(self::$_column_groups)) { 31 | self::$_column_groups = array(); 32 | foreach (ColumnGroup::search(1) as $group) { 33 | self::$_column_groups[$group->name] = $group->id; 34 | } 35 | } 36 | 37 | if (!array_key_exists($name, self::$_column_groups)) { 38 | self::$_column_groups[$name] = ColumnGroup::insert(array('name' => $name))->id; 39 | } 40 | 41 | return self::$_column_groups[$name]; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/tests/Pix/Table/AllTests.php: -------------------------------------------------------------------------------- 1 | addTestSuite('Pix_Table_TableTest'); 35 | $suite->addTestSuite('Pix_Table_TableIndexTest'); 36 | $suite->addTestSuite('Pix_Table_TableCacheTest'); 37 | $suite->addTestSuite('Pix_Table_TableRowTest'); 38 | $suite->addTestSuite('Pix_Table_TableRelationTest'); 39 | $suite->addTestSuite('Pix_Table_TableHelperTest'); 40 | $suite->addTestSuite('Pix_Table_SearchTest'); 41 | $suite->addTestSuite('Pix_Table_TableTermTest'); 42 | 43 | return $suite; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Array/Volumable.php: -------------------------------------------------------------------------------- 1 | getVolumePos() 回傳的值同格式。 16 | * @access public 17 | * @return Pix_Array_Volumable 回傳自己 18 | */ 19 | public function after($id); 20 | 21 | /** 22 | * limit 指定一次要幾筆 23 | * 24 | * @param int $limit 25 | * @access public 26 | * @return Pix_Array_Volumable 回傳自己 27 | */ 28 | public function limit($limit = 10); 29 | 30 | /** 31 | * rewind 回傳符合 ->after($after)->limit($limit) 條件的 Iterator 32 | * 33 | * @access public 34 | * @return Iteratorable 可以直接丟一個 size 是 $limit 的 array 進來。 35 | */ 36 | public function rewind(); 37 | 38 | 39 | /** 40 | * getVolumePos 回傳 $row 這個 row 在 Pix_Array_Volumable 的位置。 41 | * 42 | * @param mixed $row 這個類型要跟 rewind() 回傳的 Iterator 的 value 一樣類型 43 | * @access public 44 | * @return mixed 這個類型要跟 ->after($id) 的 $id 一樣,到時候會噴給他用 45 | */ 46 | public function getVolumePos($row); 47 | 48 | /** 49 | * getVolumeID 取得這個 Volume 的代表 ID ,用在 cache 結果用的。 50 | * 51 | * @access public 52 | * @return string|null 若為 null 的話,就不會使用 cache 53 | */ 54 | public function getVolumeID(); 55 | } 56 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/tests/Pix/Table/TableTermTest.php: -------------------------------------------------------------------------------- 1 | _primary = 'id'; 8 | 9 | $this->_columns['id'] = array('type' => 'int'); 10 | } 11 | } 12 | 13 | /** 14 | * Test class for Pix_Table_Search_Term. 15 | */ 16 | class Pix_Table_TableTermTest extends PHPUnit_Framework_TestCase 17 | { 18 | public function testSearchTerm() 19 | { 20 | $result_set = Pix_Table_TableTermTest_Table::search(1)->searchTerm('term_id', 'a', 'b'); 21 | $search = $result_set->getSearchObject(); 22 | 23 | $conditions = $search->getSearchCondictions('term'); 24 | $this->assertEquals(count($conditions), 1); 25 | list($type, $search_term) = $conditions[0]; 26 | $this->assertEquals($search_term->getType(), 'term_id'); 27 | $this->assertEquals($search_term->getArguments(), array('a', 'b')); 28 | } 29 | 30 | public function testSearchTerm2() 31 | { 32 | $term = new Pix_Table_Search_Term('term_id', 'a', 'b'); 33 | $result_set = Pix_Table_TableTermTest_Table::search($term); 34 | $search = $result_set->getSearchObject(); 35 | 36 | $conditions = $search->getSearchCondictions('term'); 37 | $this->assertEquals(count($conditions), 1); 38 | list($type, $search_term) = $conditions[0]; 39 | $this->assertEquals($search_term->getType(), 'term_id'); 40 | $this->assertEquals($search_term->getArguments(), array('a', 'b')); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Cache.php: -------------------------------------------------------------------------------- 1 | _id = $id; 17 | } 18 | 19 | public function __call($func, $args) 20 | { 21 | if (!self::$_servers[$this->_id]) { 22 | trigger_error('你應該要先做 Pix_Cache::addServer()', E_USER_WARNING); 23 | return null; 24 | } 25 | $ret = call_user_func_array(array(self::$_servers[$this->_id], $func), $args); 26 | return $ret; 27 | } 28 | 29 | 30 | protected static $_servers = array(); 31 | 32 | /** 33 | * addServer 增加 Cache Server 設定。 34 | * 35 | * @param mixed $adapter Pix_Cache 使用的 Adapter 的 class name (Ex: Pix_Cache_Adapter_Memcache) 36 | * @param array $conf 37 | * @param int $id 38 | * @static 39 | * @access public 40 | * @return void 41 | */ 42 | public static function addServer($adapter, $conf = array(), $id = 0) 43 | { 44 | if (!class_exists($adapter)) { 45 | throw new Pix_Exception('Class not found'); 46 | } 47 | 48 | $server = new $adapter($conf); 49 | if (!is_a($server, 'Pix_Cache_Core') and !is_a($server, 'Pix_Cache_Adapter')) { 50 | throw new Pix_Exception("$adapter is not a Pix_Cache_Adapter"); 51 | } 52 | self::$_servers[$id] = $server; 53 | } 54 | 55 | public static function reset() 56 | { 57 | self::$_servers = array(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Session/Adapter.php: -------------------------------------------------------------------------------- 1 | _options = $options; 36 | } 37 | 38 | public function getOption($key, $options = array()) 39 | { 40 | if (isset($options[$key])) { 41 | return $options[$key]; 42 | } 43 | if (isset($this->_options[$key])) { 44 | return $this->_options[$key]; 45 | } 46 | return Pix_Session::getOption($key); 47 | } 48 | 49 | public function hasOption($key) 50 | { 51 | return isset($this->_options[$key]); 52 | } 53 | 54 | public function setOption($key, $value) 55 | { 56 | $this->_options[$key] = $value; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Table/Search/Term.php: -------------------------------------------------------------------------------- 1 | _type = array_shift($args); 25 | if (count($args)) { 26 | $this->_arguments = $args; 27 | } 28 | } 29 | } 30 | 31 | /** 32 | * getType 33 | * 34 | * @access public 35 | * @return string 36 | */ 37 | public function getType() 38 | { 39 | return $this->_type; 40 | } 41 | 42 | /** 43 | * getArguments 44 | * 45 | * @access public 46 | * @return array 47 | */ 48 | public function getArguments() 49 | { 50 | return $this->_arguments; 51 | } 52 | 53 | /** 54 | * setType 55 | * 56 | * @param string $type 57 | * @access public 58 | * @return void 59 | */ 60 | public function setType($type) 61 | { 62 | $this->_type = $type; 63 | } 64 | 65 | /** 66 | * setArguments 67 | * 68 | * @param array $arguments 69 | * @access public 70 | * @return void 71 | */ 72 | public function setArguments($arguments) 73 | { 74 | $this->_arguments = $arguments; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /webdata/init.inc.php: -------------------------------------------------------------------------------- 1 | host = $matches[3]; 28 | $db->username = $matches[1]; 29 | $db->password = $matches[2]; 30 | $db->dbname = $matches[4]; 31 | $config = new StdClass; 32 | $config->master = $config->slave = $db; 33 | Pix_Table::setDefaultDb(new Pix_Table_Db_Adapter_MysqlConf(array($config))); 34 | 35 | if (!getenv('COMPANY_DATABASE_URL')) { 36 | die('need COMPANY_DATABASE_URL'); 37 | } 38 | if (!preg_match('#mysql://([^:]*):([^@]*)@([^/]*)/(.*)#', strval(getenv('COMPANY_DATABASE_URL')), $matches)) { 39 | die('mysql only'); 40 | } 41 | 42 | $db = new StdClass; 43 | $db->host = $matches[3]; 44 | $db->username = $matches[1]; 45 | $db->password = $matches[2]; 46 | $db->dbname = $matches[4]; 47 | $config = new StdClass; 48 | $config->master = $config->slave = $db; 49 | $company_db = new Pix_Table_Db_Adapter_MysqlConf(array($config)); 50 | Unit::setDb($company_db); 51 | UnitData::setDb($company_db); 52 | ColumnGroup::setDb($company_db); 53 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Table/Helper/CacheTime.php: -------------------------------------------------------------------------------- 1 | Pix_Cache object(default null), depends relation_name array 9 | * @package Table 10 | * @copyright 2003-2012 PIXNET Digital Media Corporation 11 | * @license http://framework.pixnet.net/license BSD License 12 | */ 13 | class Pix_Table_Helper_CacheTime extends Pix_Helper 14 | { 15 | protected function _getCacheExpire() 16 | { 17 | return ($expire = $this->getOption('cache_expire')) ? $expire : 3600; 18 | } 19 | 20 | protected function _getCache() 21 | { 22 | if ($cache = $this->getOption('cache')) { 23 | return $cache; 24 | } 25 | throw new Exception('需要指定 Pix_Cache object'); 26 | } 27 | 28 | public function getCacheTime($obj, $group = 'default') 29 | { 30 | $cache = $this->_getCache(); 31 | $cache_key = 'Pix_Table_Helper_CacheTime:' . $obj->getUniqueID() . ':' . $group; 32 | if (!$time = $cache->get($cache_key)) { 33 | $time = time(); 34 | $cache->set($cache_key, $time); 35 | } 36 | return $time; 37 | } 38 | 39 | public function updateCacheTime($obj, $group = 'default') 40 | { 41 | $cache = $this->_getCache(); 42 | $cache_key = 'Pix_Table_Helper_CacheTime:' . $obj->getUniqueID() . ':' . $group; 43 | 44 | $cache->set($cache_key, time()); 45 | if ($depends = $this->getOption('depends') and is_array($depends)) { 46 | foreach ($depends as $depend_rel) { 47 | if (is_array($depend_rel)) { 48 | list($rel, $group) = $depend_rel; 49 | $obj->{$rel}->updateCacheTime($group); 50 | } else { 51 | $obj->{$depend_rel}->updateCacheTime(); 52 | } 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Partial/Helper/Html.php: -------------------------------------------------------------------------------- 1 | $val) { 21 | $optionHtml .= sprintf(' %s="%s"', $key, $partial->escape($val)); 22 | } 23 | return sprintf('%s', $partial->escape($href), $optionHtml, $text); 24 | } 25 | 26 | public function image_tag($partial, $src, $html_options = array(), $extra_options = array()) 27 | { 28 | $optionHtml = ''; 29 | if ($maxsize = intval($extra_options['maxsize'])) { 30 | if (($h = intval($extra_options['height'])) and ($w = intval($extra_options['width']))) { 31 | $bigger_side = max($h, $w); 32 | if ($bigger_side > $maxsize) { 33 | $html_options['width'] = intval(ceil($w * $maxsize) / $bigger_side); 34 | $html_options['height'] = intval(ceil($h * $maxsize) / $bigger_side); 35 | } 36 | } else { 37 | $html_options['width'] = $html_options['height'] = $maxsize; 38 | } 39 | } 40 | foreach ($html_options as $key => $val) { 41 | $optionHtml .= sprintf(' %s="%s"', $key, $partial->escape($val)); 42 | } 43 | return sprintf('', $partial->escape($src), $optionHtml); 44 | } 45 | 46 | public function urlArg($partial, $args) 47 | { 48 | $urlarg = new Pix_UrlArg; 49 | foreach ($args as $k => $v) { 50 | $urlarg->$k = $v; 51 | } 52 | 53 | return strval($urlarg); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /webdata/views/index/about.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 台灣公司關係圖 6 | 7 | 8 | 19 | 20 | 21 | 22 | 回首頁 23 |

關於本資料注意事項

24 |
    25 |
  1. 資料來源是 台灣公司資料 ,不一定會與經濟部商業司資料同步
  2. 26 |
  3. [Updated 2018-10-12] 自 2018-10 起,資料會自動每月一次從 台灣公司資料 更新,並且在頁面上會顯示最近更新日期,以便得知目前資料版本
  4. 27 |
  5. 這邊的圖表是以查詢的公司往外最多查詢三層關係,因此有的公司在圖表中沒看到關係,不代表他已經沒有其他關係公司,只是離你正在查詢的公司太遠了,想要確認是否有這狀況,可以再從那個不確定是否有關係的公司再查詢一次
  6. 28 |
  7. 資料呈現上沒有顯示方向性,因此 A公司 與 B公司 被線連起來,有可能是 A 持有 B ,也有可能是 B 持有 A
  8. 29 |
  9. 公司的關聯是透過「董事名單」,如果有持股但是沒有被列入董事不會在這邊出現
  10. 30 |
  11. 如果公司是以個人持股而非代表法人持股,也不會從這邊看的到關聯
  12. 31 |
  13. 兩家公司出現在這邊不代表是同集團,例如 中華職棒事業股份有限公司 的董事有 統一企業股份有限公司味全食品工業股份有限公司 ,但是統一和味全並不是同一集團。
  14. 32 |
  15. 程式碼以 BSD License 公開在 https://github.com/ronnywang/company-graph,歡迎 PULL REQUEST 更好看及更好用的呈現方式
  16. 33 |
34 | 35 | 36 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Controller/DefaultErrorController/views/error/error.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

Pix_Controller catch a exception

8 | Exception class: exception) ?>
9 | Exception message: escape($this->exception->getMessage()) ?>
10 | Stack trace:
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | exception->getTrace() as $trace) { ?> 19 | 20 | 21 | 22 | 23 | 40 | 41 | 42 |
FileLineFunctionArguments
escape($trace['file']) ?>escape($trace['class'] . $trace['type'] . $trace['function']) ?> 24 |
    25 | 26 |
  1. 27 | 28 | string: escape($arg) ?> 29 | 30 | array() 31 | 32 | 33 | 34 | 35 | 36 |
  2. 37 | 38 |
39 |
43 |
44 |
45 | This is Pix_Controller default error page. If you want to modify this, you can add ErrorController.php in webdata/controllers/
46 | Pix Framework 47 |
48 | 49 | 50 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Cache/Adapter.php: -------------------------------------------------------------------------------- 1 | get($key); 24 | } 25 | public function save($key, $value, $options = array()) 26 | { 27 | return $this->set($key, $value, $options); 28 | } 29 | public function remove($key) 30 | { 31 | return $this->delete($key); 32 | } 33 | 34 | /** 35 | * gets 一次 get 多筆功能 36 | * 37 | * @param array $keys 要抓的 key 的 array 38 | * @access public 39 | * @return array 40 | */ 41 | public function gets($keys) 42 | { 43 | $ret = array(); 44 | foreach ($keys as $key) { 45 | $data = $this->get($key); 46 | if (false === $data) { 47 | continue; 48 | } 49 | $ret[$key] = $data; 50 | } 51 | return $ret; 52 | } 53 | 54 | /** 55 | * sets 一次指定多筆功能 56 | * 57 | * @param array $keys_values key, value 的 associate array 58 | * @access public 59 | * @return void 60 | */ 61 | public function sets($keys_values) 62 | { 63 | foreach ($keys_values as $key => $value) { 64 | $this->set($key, $value); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Controller/Helper/Json.php: -------------------------------------------------------------------------------- 1 | checkCanGzip()) { 26 | ob_start(); 27 | ob_implicit_flush(0); 28 | echo @json_encode($obj); 29 | $contents = ob_get_contents(); 30 | ob_end_clean(); 31 | header("Content-Encoding: " . $encoding); 32 | print gzencode($contents); 33 | return $controller->noview(); 34 | } 35 | 36 | echo @json_encode($obj); 37 | return $controller->noview(); 38 | } 39 | 40 | public function jsonp($controller, $obj, $callback) 41 | { 42 | header('Content-Type: application/javascript'); 43 | if (!preg_match('/^[a-zA-Z0-9_\.]+$/', strval($callback))) { 44 | return $controller->json($obj); 45 | } 46 | echo $callback . '(' . @json_encode($obj) . ')'; 47 | return $controller->noview(); 48 | } 49 | 50 | public function checkCanGzip() { 51 | 52 | if (headers_sent()) return 0; 53 | if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip') !== false) return 54 | "x-gzip"; 55 | if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip') !== false) return 56 | "gzip"; 57 | return 0; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/tests/Pix/Table/TableIndexTest.php: -------------------------------------------------------------------------------- 1 | _name = 'user'; 8 | $this->_primary = 'id'; 9 | 10 | $this->_columns['id'] = array('type' => 'int', 'auto_increment' => true); 11 | $this->_columns['name'] = array('type' => 'varchar', 'size' => 32); 12 | $this->_columns['password'] = array('type' => 'varchar', 'size' => 32, 'default' => ''); 13 | 14 | $this->addIndex('name', array('name'), 'unique'); 15 | } 16 | } 17 | 18 | class Pix_Table_TestIndexTest_Article extends Pix_Table 19 | { 20 | public function init() 21 | { 22 | $this->_name = 'article'; 23 | $this->_primary = 'id'; 24 | 25 | $this->_columns['id'] = array('type' => 'int', 'auto_increment' => true); 26 | $this->_columns['user_id'] = array('type' => 'int'); 27 | $this->_columns['time'] = array('type' => 'int'); 28 | $this->_columns['title'] = array('type' => 'varchar', 'size' => 32, 'default' => ''); 29 | 30 | $this->_relations['user'] = array('rel' => 'has_one', 'type' => 'Pix_Table_TestIndexTest_User', 'foreign_key' => 'user_id', 'delete' => true); 31 | 32 | $this->addIndex('userid_time', array('user_id', 'time')); 33 | } 34 | } 35 | 36 | 37 | class Pix_Table_TableIndexTest extends PHPUnit_Framework_TestCase 38 | { 39 | public function test() 40 | { 41 | $this->assertEquals('PRIMARY', Pix_Table_TestIndexTest_User::findUniqueKey(array('id'))); 42 | $this->assertEquals('PRIMARY', Pix_Table_TestIndexTest_Article::findUniqueKey(array('id', 'user_id'))); 43 | $this->assertEquals(null, Pix_Table_TestIndexTest_Article::findUniqueKey(array('user_id'))); 44 | $this->assertEquals('name', Pix_Table_TestIndexTest_User::findUniqueKey(array('name'))); 45 | $this->assertEquals('name', Pix_Table_TestIndexTest_User::findUniqueKey(array('name', 'password'))); 46 | 47 | $this->assertEquals(Pix_Table_TestIndexTest_Article::getIndexColumns('userid_time'), array('user_id', 'time')); 48 | $this->assertEquals(Pix_Table_TestIndexTest_Article::getIndexColumns('PRIMARY'), array('id')); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 台灣公司關係圖 2 | ============== 3 | 這裡是 [台灣公司關係圖](https://company-graph.g0v.ronny.tw/) 的程式碼,若要安裝台灣公司關係圖,您也需要安裝 [台灣公司資料](https://github.com/ronnywang/twcompany) 並且匯入資料 4 | 5 | License 6 | ------- 7 | * 程式為 BSD License 授權 8 | * [pixframework](https://github.com/pixnet/pixframework) BSD License 9 | * [jQuery](https://jquery.org/license/) BSD License 10 | * [ignacioola/insights](https://github.com/ignacioola/insights) MIT License 11 | 12 | 安裝說明 13 | -------- 14 | * 需要有 php, php-mysqlnd, php-mbstring, php-json, php-dom, wget 15 | * 需要先有安裝好 [台灣公司資料](https://github.com/ronnywang/twcompany) 以及匯入好的資料庫 16 | * git clone https://github.com/ronnywang/company-graph 17 | * cd company-graph/webdata 18 | * cp config.sample.php config.php 19 | * 修改 COMPANY_DATABASE_URL,改成 台灣公司資料 的資料庫位置 20 | * 修改 DATABASE\_URL 成給公司關係圖專用資料 21 | * php webdata/scripts/init-db.php 22 | * 建立起需要的資料表 23 | * php webdata/scripts/import-data.php 24 | * 匯入資料庫 25 | 26 | 資料表說明 27 | ---------- 28 | * 經濟部商業司資料 29 | * columngroup: 定義資料欄位組合 30 | * unit: 各單位資料表 31 | * unit_data: 各單位欄位的值 32 | * unitchangelog: 各單位欄位值變動記錄 33 | * 財政部資料 34 | * fia_columngroup: 定義資料欄位組合 35 | * fia_unit_data: 各單位欄位的值 36 | * fia_unitchangelog: 各單位欄位值變動記錄 37 | * 其他 38 | * key_value: 一些環境變數組合,例如最近一次更新時間 39 | 40 | 相關程式說明 41 | ------------ 42 | * webdata/scripts/ 43 | * php crawler.php \[compnay|bussiness] YYYMM 44 | * 從 [經濟部商業司 公司資料異動清冊](https://serv.gcis.nat.gov.tw/pub/cmpy/reportReg.jsp) 抓取上個月設立、變更、解散公司或商號更新資料 45 | * 每月執行一次,大約在每月 5 號左右 46 | * php update-tax.php 47 | * 從 [財政部 全國營業(稅籍)登記資料集](https://data.gov.tw/dataset/9400) 抓取每日更新資料 48 | * 每日執行一次,下載完整資料後會與資料庫比對有更改的記錄,有更改的部份會順便更新經濟部資料 49 | * php dump-gcis-history.php 50 | * 匯出商業司變更記錄,[位置](http://ronnywang-twcompany.s3-website-ap-northeast-1.amazonaws.com/gcis-history/) 51 | * php dump-index.php 52 | * 匯出列表檔案,[位置](http://ronnywang-twcompany.s3-website-ap-northeast-1.amazonaws.com/index.csv.gz) 53 | * php dump-tax.php 54 | * 匯出財政部變更記錄,[位置](http://ronnywang-twcompany.s3-website-ap-northeast-1.amazonaws.com/tax-history) 55 | * php dump.php 56 | * 匯出完整經濟部打包檔,[位置](http://ronnywang-twcompany.s3-website-ap-northeast-1.amazonaws.com/files/) 57 | 58 | 相關連結 59 | -------- 60 | * [台灣公司關係圖](https://company-graph.g0v.ronny.tw) 61 | * [台灣公司關係圖程式](https://github.com/ronnywang/company-graph) 62 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Table/Helper/EAV.php: -------------------------------------------------------------------------------- 1 | relation name (default eavs) 8 | * @package Table 9 | * @copyright 2003-2012 PIXNET Digital Media Corporation 10 | * @license http://framework.pixnet.net/license BSD License 11 | */ 12 | class Pix_Table_Helper_EAV extends Pix_Helper 13 | { 14 | protected function _getRelation() 15 | { 16 | return ($relation = $this->getOption('relation')) ? $relation : 'eavs'; 17 | } 18 | 19 | protected function _getKeyColumn() 20 | { 21 | return ($column = $this->getOption('key_column')) ? $column : 'key'; 22 | } 23 | 24 | protected function _getValueColumn() 25 | { 26 | return ($column = $this->getOption('value_column')) ? $column : 'value'; 27 | } 28 | 29 | public function incEAV($row, $key, $delta = 1, $max = null) 30 | { 31 | // TODO : 如果 backend support a = a + 1 就應該改用 a = a + 1 用法 32 | if (is_null($max)) { 33 | $this->setEAV($row, $key, intval($this->getEAV($row, $key)) + $delta); 34 | } else { 35 | $this->setEAV($row, $key, min(intval($this->getEAV($row, $key)) + $delta, $max)); 36 | } 37 | } 38 | 39 | public function decEAV($row, $key, $delta = 1, $min = null) 40 | { 41 | // TODO : 如果 backend support a = a + 1 就應該改用 a = a + 1 用法 42 | if (is_null($min)) { 43 | $this->setEAV($row, $key, intval($this->getEAV($row, $key)) - $delta); 44 | } else { 45 | $this->setEAV($row, $key, max(intval($this->getEAV($row, $key)) - $delta, $min)); 46 | } 47 | } 48 | 49 | public function getEAV($row, $key) 50 | { 51 | $key_column = $this->_getKeyColumn(); 52 | $value_column = $this->_getValueColumn(); 53 | $data = ($eav = $row->{$this->_getRelation()}->search(array($key_column => $key))->first()) ? $eav->{$value_column} : null; 54 | 55 | return $data; 56 | } 57 | 58 | public function setEAV($row, $key, $value) 59 | { 60 | $key_column = $this->_getKeyColumn(); 61 | $value_column = $this->_getValueColumn(); 62 | if (is_null($value)) { 63 | $row->{$this->_getRelation()}->search(array($key_column => $key))->delete(); 64 | return true; 65 | } 66 | 67 | try { 68 | $row->{$this->_getRelation()}->insert(array($key_column => $key, $value_column => $value)); 69 | } catch (Pix_Table_DuplicateException $e) { 70 | $row->{$this->_getRelation()}->search(array($key_column => $key))->update(array($value_column => $value)); 71 | } 72 | return true; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Table/Db.php: -------------------------------------------------------------------------------- 1 | host = $matches[3]; 34 | $db->username = $matches[1]; 35 | $db->password = $matches[2]; 36 | $db->dbname = $matches[4]; 37 | $config = new StdClass; 38 | $config->master = $config->slave = $db; 39 | Pix_Table::setDefaultDb(new Pix_Table_Db_Adapter_MysqlConf(array($config))); 40 | } elseif (strpos($uri, 'pgsql://') === 0) { 41 | if (!preg_match('#pgsql://([^:]*):([^@]*)@([^/:]*):?([0-9]*)?/(.*)#', strval($uri), $matches)) { 42 | throw new Exception("wrong pgsql URI format, must be pgsql://{user}:{password}@{host}/{db}"); 43 | } 44 | $options = array( 45 | 'host' => $matches[3], 46 | 'user' => $matches[1], 47 | 'password' => $matches[2], 48 | 'dbname' => $matches[5], 49 | ); 50 | if ($matches[4]) { 51 | $options['port'] = $matches[4]; 52 | } 53 | Pix_Table::setDefaultDb(new Pix_Table_Db_Adapter_PgSQL($options)); 54 | } elseif (strpos($uri, 'sqlite://') === 0) { 55 | $file = substr($uri, strlen('sqlite://')); 56 | Pix_Table::setDefaultDb(new Pix_Table_Db_Adapter_Sqlite($file)); 57 | } else { 58 | throw new Exception("add DB failed, unknown uri {$uri}"); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Cache/Adapter/HandlerSocket.php: -------------------------------------------------------------------------------- 1 | _config = $config; 20 | } 21 | 22 | public function getSocket($type = 'read') 23 | { 24 | $type = in_array($type, array('read', 'write')) ? $type : 'read'; 25 | 26 | if (is_null($this->_hs[$type])) { 27 | $config = $this->_config; 28 | if (!is_array($config)) { 29 | throw new Pix_Exception('config error'); 30 | } 31 | 32 | $hs = new HandlerSocket($config[$type]['host'], $config[$type]['port']); 33 | if ('write' == $type) { 34 | if (!$hs->openIndex(1, $config[$type]['dbname'], $config[$type]['table'], '', 'value')) { 35 | throw new Exception($hs->getError()); 36 | } 37 | } else { 38 | if (!$hs->openIndex(1, $config[$type]['dbname'], $config[$type]['table'], HandlerSocket::PRIMARY, 'key,value')) { 39 | throw new Exception($hs->getError()); 40 | } 41 | } 42 | $this->_hs[$type] = $hs; 43 | } 44 | return $this->_hs[$type]; 45 | } 46 | 47 | protected function _getOptions($options) 48 | { 49 | $ret = array(); 50 | $ret['expire'] = is_int($options) ? $options : (isset($options['expire']) ? $options['expire'] : 3600); 51 | $ret['compress'] = isset($options['compress']) ? $options['compress'] : false; 52 | return $ret; 53 | } 54 | 55 | public function add($key, $value, $options = array()) 56 | { 57 | $this->set($key, $value); 58 | } 59 | 60 | public function set($key, $value, $options = array()) 61 | { 62 | $hs = $this->getSocket('write'); 63 | if (!$hs->executeInsert(1, array($key, $value))) { 64 | $hs->executeUpdate(1, '=', array($key), array($value), 1, 0); 65 | } 66 | } 67 | 68 | public function delete($key) 69 | { 70 | $hs = $this->getSocket('write'); 71 | if (!$hs->executeDelete(1, '=', array($key))) { 72 | return 0; 73 | } 74 | return 1; 75 | } 76 | 77 | public function replace($key, $value, $options = array()) 78 | { 79 | $this->set($key, $value); 80 | } 81 | 82 | public function inc($key, $inc = 1) 83 | { 84 | throw new Exception('not implemented'); 85 | } 86 | 87 | public function dec($key, $inc = 1) 88 | { 89 | throw new Exception('not implemented'); 90 | } 91 | 92 | public function get($key) 93 | { 94 | $hs = $this->getSocket(); 95 | $retval = $hs->executeSingle(1, '=', array($key), 1, 0); 96 | 97 | return ($retval[0][1]); 98 | } 99 | 100 | /*public function gets(array $keys) 101 | { 102 | $memcache = $this->getMemcache(); 103 | return $memcache->get($keys); 104 | } */ 105 | } 106 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Session.php: -------------------------------------------------------------------------------- 1 | addHelper($helper, $methods, $options); 69 | } 70 | 71 | public static function __callStatic($name, $args) 72 | { 73 | return self::__call($name, $args); 74 | } 75 | 76 | public function __call($name, $args) 77 | { 78 | array_unshift($args, $this); 79 | return self::getHelperManager()->callHelper($name, $args); 80 | } 81 | 82 | public static function get($key) 83 | { 84 | $obj = self::getObject(); 85 | return $obj->get($key); 86 | } 87 | 88 | public static function set($key, $value) 89 | { 90 | $obj = self::getObject(); 91 | return $obj->set($key, $value); 92 | } 93 | 94 | public static function delete($key) 95 | { 96 | $obj = self::getObject(); 97 | return $obj->delete($key); 98 | } 99 | 100 | public static function clear() 101 | { 102 | $obj = self::getObject(); 103 | return $obj->clear(); 104 | } 105 | 106 | public static function setOption($key, $value) 107 | { 108 | $obj = self::getObject(); 109 | return $obj->setOption($key, $value); 110 | } 111 | 112 | public static function getOption($key) 113 | { 114 | $obj = self::getObject(); 115 | return $obj->getOption($key); 116 | } 117 | 118 | public function __get($key) 119 | { 120 | return self::get($key); 121 | } 122 | 123 | public function __set($key, $value) 124 | { 125 | return self::set($key, $value); 126 | } 127 | 128 | public function __unset($key) 129 | { 130 | return self::delete($key); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Table/Db/Adapter/Mysqli.php: -------------------------------------------------------------------------------- 1 | _link = $link; 18 | } 19 | 20 | public function getSupportFeatures() 21 | { 22 | return array('immediate_consistency', 'check_table'); 23 | } 24 | 25 | /** 26 | * __get 為了與 MySQLi object 相容所加的 __get($name); 27 | * 28 | * @param mixed $name 29 | * @access public 30 | * @return void 31 | */ 32 | public function __get($name) 33 | { 34 | return $this->_link->{$name}; 35 | } 36 | 37 | /** 38 | * __call 為了與 MySQLi 相容所加的 __call() 39 | * 40 | * @param mixed $name 41 | * @param mixed $args 42 | * @access public 43 | * @return void 44 | */ 45 | public function __call($name, $args) 46 | { 47 | return call_user_func_array(array($this->_link, $name), $args); 48 | } 49 | 50 | /** 51 | * query 對 db 下 SQL query 52 | * 53 | * @param mixed $sql 54 | * @access protected 55 | * @return Mysqli result 56 | */ 57 | public function query($sql, $table = null) 58 | { 59 | $short_sql = mb_strimwidth($sql, 0, 512, "...len=" . strlen($sql)); 60 | if (Pix_Table::$_log_groups[Pix_Table::LOG_QUERY]) { 61 | Pix_Table::debug(sprintf("[%s]\t%40s", $this->_link->host_info, $short_sql)); 62 | } 63 | // TODO 需要 log SQL Query 功能 64 | if ($comment = Pix_Table::getQueryComment()) { 65 | $sql = trim($sql, '; ') . ' #' . $comment; 66 | } 67 | 68 | $starttime = microtime(true); 69 | $res = $this->_link->query($sql); 70 | if (($t = Pix_Table::getLongQueryTime()) and ($delta = (microtime(true) - $starttime)) > $t) { 71 | Pix_Table::debug(sprintf("[%s]\t%s\t%40s", $this->_link->host_info, $delta, $sql)); 72 | } 73 | 74 | if ($res === false) { 75 | if ($errno = $this->_link->errno) { 76 | switch ($errno) { 77 | case 1062: 78 | throw new Pix_Table_DuplicateException($this->_link->error, $errno); 79 | case 1406: 80 | throw new Pix_Table_DataTooLongException($this->_link->error, $errno); 81 | default: 82 | throw new Exception("SQL Error: {$this->_link->error} SQL: $sql"); 83 | } 84 | } 85 | } 86 | return $res; 87 | } 88 | 89 | /** 90 | * quote 將 $str 字串內容 quote 起來。 91 | * 92 | * @param string $str 93 | * @access public 94 | * @return string 95 | */ 96 | public function quoteWithColumn($table, $value, $column_name) 97 | { 98 | if (is_null($column_name)) { 99 | return "'" . $this->_link->real_escape_string(strval($value)) . "'"; 100 | } 101 | if ($table->isNumbericColumn($column_name)) { 102 | return intval($value); 103 | } 104 | if (!is_scalar($value)) { 105 | trigger_error("{$_SERVER['SERVER_NAME']}{$_SERVER['REQUEST_URI']} 的 column `{$column_name}` 格式不正確: " . gettype($value), E_USER_WARNING); 106 | } 107 | return "'" . $this->_link->real_escape_string(strval($value)) . "'"; 108 | } 109 | 110 | public function getLastInsertId($table) 111 | { 112 | return $this->_link->insert_id; 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /webdata/views/index/index.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <?= $this->unit_title ? $this->escape($this->unit_title . " | ") : "" ?>台灣公司關係圖 6 | 7 | 8 | 9 | 10 | 21 | 22 | 23 | 24 |
25 | 查詢統一編號、完整公司名稱、法人名稱或政府機關名稱: 26 | 關於本站資料(資料更新時間:) 27 | 台灣公司資料查詢 28 |
29 | id) { ?> 30 | 計算關係中... 31 | 32 |
33 | 35 |
36 |
37 | 38 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Session/Adapter/Cookie.php: -------------------------------------------------------------------------------- 1 | _getCookieKey()], 2); 19 | if (!$secret = $this->getOption('secret')) { 20 | throw new Pix_Exception('you should set the option `secret`'); 21 | } 22 | if ($this->_sig($data . $this->_getCookieDomain(), $secret) != $sig) { 23 | return; 24 | } 25 | 26 | $data = json_decode($data, true); 27 | 28 | $this->_data = $data; 29 | } 30 | 31 | protected function _getSignatureMethod() 32 | { 33 | return $this->hasOption('signature_method') ? $this->getOption('signature_method') : 'hmac_sha256'; 34 | } 35 | 36 | protected function _getCookieKey() 37 | { 38 | return $this->hasOption('cookie_key') ? $this->getOption('cookie_key') : session_name(); 39 | } 40 | 41 | protected function _getCookiePath() 42 | { 43 | return $this->hasOption('cookie_path') ? $this->getOption('cookie_path') : '/'; 44 | } 45 | 46 | protected function _getCookieDomain() 47 | { 48 | return $this->hasOption('cookie_domain') ? $this->getOption('cookie_domain') : $_SERVER['HTTP_HOST']; 49 | } 50 | 51 | protected function _getSecure() 52 | { 53 | return $this->hasOption('secure') ? $this->getOption('secure') : false; 54 | } 55 | 56 | protected function _getTimeout() 57 | { 58 | return $this->hasOption('timeout') ? $this->getOption('timeout') : null; 59 | } 60 | 61 | protected function setCookie() 62 | { 63 | $data = json_encode($this->_data); 64 | $sig = $this->_sig($data . $this->_getCookieDomain(), $this->getOption('secret')); 65 | $params = session_get_cookie_params(); 66 | Pix_HttpResponse::setcookie( 67 | $this->_getCookieKey(), 68 | $sig . '|' . $data, 69 | $this->_getTimeout() ? (time() + $this->_getTimeout()) : null, 70 | $this->_getCookiePath(), 71 | $this->_getCookieDomain(), 72 | $this->_getSecure() 73 | ); 74 | } 75 | 76 | public function set($key, $value) 77 | { 78 | if ($this->_data[$key] !== $value) { 79 | $this->_data[$key] = $value; 80 | $this->setCookie(); 81 | } 82 | } 83 | 84 | protected function _sig($string, $secret) 85 | { 86 | $signature_method = $this->_getSignatureMethod(); 87 | 88 | if (is_scalar($signature_method) and in_array($signature_method, array('crc32', 'hmac_sha256'))) { 89 | switch ($signature_method) { 90 | case 'crc32': 91 | return crc32($string . $secret); 92 | case 'hmac_sha256': 93 | return hash_hmac('sha256', $string, $secret); 94 | } 95 | } 96 | 97 | if (is_callable($signature_method)) { 98 | return call_user_func($signature_method, $string); 99 | } 100 | 101 | throw new Pix_Exception('unknown signature method'); 102 | } 103 | 104 | public function get($key) 105 | { 106 | return $this->_data[$key]; 107 | } 108 | 109 | public function delete($key) 110 | { 111 | unset($this->_data[$key]); 112 | $this->setCookie(); 113 | } 114 | 115 | public function clear() 116 | { 117 | $this->_data = array(); 118 | $this->setCookie(); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Controller/Helper/Http.php: -------------------------------------------------------------------------------- 1 | = $options['last_modified_time']) { 22 | $not_modified = true; 23 | } else { 24 | $not_modified = false; 25 | } 26 | 27 | if ($options['last_modified_time']) { 28 | header('Age: ' . (time() - $options['last_modified_time'])); 29 | } 30 | 31 | $max_age = isset($options['max_age']) ? intval($options['max_age']) : 86400; 32 | // 有 Last-Modified-Time 的話, max-age 會按照 Last-Modified-Time 起算, 不是 max-age 之後 expire 33 | if (!$options['last_modified_time']) { 34 | header('Cache-Control: max-age=' . $max_age); 35 | } 36 | 37 | if ($not_modified) { 38 | header("HTTP/1.1 304 Not Modified"); 39 | return $controller->noview(); 40 | } 41 | 42 | if ($options['last_modified_time']) { 43 | header('Last-Modified: ' . date("r", $options['last_modified_time'])); 44 | header('Expires: ' . date("r", time() + $max_age)); 45 | } 46 | if ($options['etag']) { 47 | header('Etag: ' . $options['etag']); 48 | } 49 | // 不要設定 Pragma 50 | header('Pragma: '); 51 | } 52 | 53 | /** 54 | * isGet 判斷是否為 GET 55 | * 56 | */ 57 | public function isGet($controller) 58 | { 59 | if ('GET' == $_SERVER['REQUEST_METHOD']) { 60 | return TRUE; 61 | } 62 | 63 | return FALSE; 64 | } 65 | 66 | /** 67 | * isDelete 判斷是否為 Delete 68 | * 69 | */ 70 | public function isDelete($controller) 71 | { 72 | if ('DELETE' == $_SERVER['REQUEST_METHOD']) { 73 | return TRUE; 74 | } 75 | 76 | if ('POST' == $_SERVER['REQUEST_METHOD'] and array_key_exists('_method', $_POST) and 'delete' == strtolower($_POST['_method'])) { 77 | return TRUE; 78 | } 79 | 80 | return FALSE; 81 | } 82 | 83 | /** 84 | * isPost 判斷是否為 POST 85 | * 86 | */ 87 | public function isPost($controller, $raw = FALSE) 88 | { 89 | // 不是 POST HTTP method 的一定不會是 POST 90 | if ('POST' != $_SERVER['REQUEST_METHOD']) { 91 | return FALSE; 92 | } 93 | 94 | // 如果表示只看 raw status,加上這邊一定會是 POST HTTP method,就直接傳回 TRUE 95 | if ($raw) { 96 | return TRUE; 97 | } 98 | 99 | // 如果沒有 _method (表示不是 convention),傳回 TRUE 100 | if (!array_key_exists('_method', $_POST)) { 101 | return TRUE; 102 | } 103 | 104 | // 如果有 _method,就要判斷裡面是不是 post 105 | if ('post' == strtolower($_POST['_method'])) { 106 | return TRUE; 107 | } 108 | 109 | // 剩下都是 FALSE 110 | return FALSE; 111 | } 112 | 113 | /** 114 | * isPut 判斷是否為 Put 115 | * 116 | */ 117 | public function isPut($controller) 118 | { 119 | if ('PUT' == $_SERVER['REQUEST_METHOD']) { 120 | return TRUE; 121 | } 122 | 123 | if ('POST' == $_SERVER['REQUEST_METHOD'] and array_key_exists('_method', $_POST) and 'put' == strtolower($_POST['_method'])) { 124 | return TRUE; 125 | } 126 | 127 | return FALSE; 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Array/Volume/ResultSet.php: -------------------------------------------------------------------------------- 1 | _origin_array = $array; 29 | $this->_chunk = isset($options['chunk']) ? intval($options['chunk']) : 100; 30 | $this->_volume_id = isset($options['id']) ? $options['id'] : $array->getVolumeID(); 31 | $this->_simple_mode = isset($options['simple_mode']) ? intval($options['simple_mode']) : false; 32 | } 33 | 34 | public function rewind() 35 | { 36 | $this->_last_row = $this->_after; 37 | $this->_pos = 0; 38 | $this->_array = Pix_Array::factory( 39 | $this->_origin_array 40 | ->after($this->_origin_array->getVolumePos($this->_last_row)) 41 | ->limit($this->_chunk) 42 | ->rewind() 43 | ); 44 | return $this; 45 | } 46 | 47 | public function first() 48 | { 49 | return $this->rewind()->current(); 50 | } 51 | 52 | public function current() 53 | { 54 | $this->_last_row = $this->_array->current(); 55 | 56 | if ($this->_simple_mode) { 57 | return $this->_last_row; 58 | } 59 | return new Pix_Array_Volume_Row($this->_last_row, $this); 60 | } 61 | 62 | public function key() 63 | { 64 | return $this->_array->key(); 65 | } 66 | 67 | public function next() 68 | { 69 | $this->_array->next(); 70 | if (0 !== $this->_limit and !$this->valid()) { 71 | $this->_array = Pix_Array::factory($this->_origin_array->after($this->_origin_array->getVolumePos($this->_last_row))->limit($this->_chunk)->rewind()); 72 | } 73 | } 74 | 75 | public function valid() 76 | { 77 | if (!is_null($this->_limit) and ($this->_pos >= $this->_offset + $this->_limit)) { 78 | return false; 79 | } 80 | return $this->_array->valid(); 81 | } 82 | 83 | public function offset($offset) 84 | { 85 | $rs = clone $this; 86 | $rs->_offset = $offset; 87 | return $rs; 88 | } 89 | 90 | public function after($row) 91 | { 92 | $rs = clone $this; 93 | $rs->_after = $row; 94 | return $rs; 95 | } 96 | 97 | public function limit($limit) 98 | { 99 | $rs = clone $this; 100 | $rs->_limit = $limit; 101 | return $rs; 102 | } 103 | 104 | public function rowOk($row) 105 | { 106 | if ($this->_pos < $this->_offset) { 107 | $this->_pos ++; 108 | return false; 109 | } 110 | if (is_null($this->_limit)) { 111 | $this->_pos ++; 112 | return true; 113 | } 114 | if ($this->_limit + $this->_offset > $this->_pos) { 115 | $this->_pos ++; 116 | return true; 117 | } 118 | return false; 119 | } 120 | 121 | /** 122 | * getPos 取得一個 string ,之後可以當作 after 來用。 123 | * 124 | * @access public 125 | * @return void 126 | */ 127 | public function getPos($row) 128 | { 129 | return $this->_array->getVolumePos($row->getRow()); 130 | } 131 | 132 | public function getOrder($row) 133 | { 134 | return $this->_pos; 135 | } 136 | 137 | public function count() 138 | { 139 | if ($this->_after) { 140 | return count($this->_origin_array->after($this->_after)); 141 | } 142 | return count($this->_origin_array); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/tests/Pix/Helper/HelperTest.php: -------------------------------------------------------------------------------- 1 | getOption($name) . ':test'; 18 | } 19 | } 20 | 21 | class Pix_Helper_HelperTest_NotPixHelper 22 | { 23 | } 24 | 25 | class Pix_Helper_HelperTest extends PHPUnit_Framework_TestCase 26 | { 27 | public function testManager() 28 | { 29 | $manager = new Pix_Helper_Manager(); 30 | $manager->addHelper('Pix_Helper_HelperTest_Helper1'); 31 | 32 | $this->assertTrue($manager->hasMethod('test1')); 33 | 34 | $this->assertEquals($manager->getMethods(), array('test1')); 35 | 36 | $this->assertEquals($manager->callHelper('test1', array()), 'test1 returned'); 37 | } 38 | 39 | public function testOption() 40 | { 41 | $manager = new Pix_Helper_Manager(); 42 | $manager->addHelper('Pix_Helper_HelperTest_Helper1', array('testOption'), array('test1' => 'value1', 'test2' => 'value2')); 43 | 44 | $this->assertEquals($manager->callHelper('testOption', array('test1')), 'value1:test'); 45 | $this->assertEquals($manager->callHelper('testOption', array('test2')), 'value2:test'); 46 | $this->assertEquals($manager->callHelper('testOption', array('not_exists_option')), ':test'); 47 | 48 | } 49 | 50 | /** 51 | * test invalid helper name in Pix_Helper_Manager->addHelper(); 52 | * @expectedException Pix_Helper_Exception 53 | */ 54 | public function testInvalidHelperName() 55 | { 56 | $manager = new Pix_Helper_Manager(); 57 | $manager->addHelper(array()); 58 | } 59 | 60 | /** 61 | * test not exists helper class name 62 | * @expectedException Pix_Helper_Exception 63 | */ 64 | public function testNotExistedHelperClass() 65 | { 66 | $manager = new Pix_Helper_Manager(); 67 | $manager->addHelper('Pix_Helper_HelperTest_HelperNotExists'); 68 | } 69 | 70 | /** 71 | * test not exists helper class name (addHelper with $methods, it will throw exception in callHelper) 72 | * @expectedException Pix_Helper_Exception 73 | */ 74 | public function testNotExistedHelperClass2() 75 | { 76 | $manager = new Pix_Helper_Manager(); 77 | $manager->addHelper('Pix_Helper_HelperTest_HelperNotExists', array('test')); 78 | $manager->callHelper('test', array()); 79 | } 80 | 81 | /** 82 | * test addHelper() which is not Pix_Helper 83 | * @expectedException Pix_Helper_Exception 84 | */ 85 | public function testNotPixHelperHelperClass() 86 | { 87 | $manager = new Pix_Helper_Manager(); 88 | $manager->addHelper('Pix_Helper_HelperTest_NotPixHelper'); 89 | } 90 | 91 | /** 92 | * test addHelper() which is not Pix_Helper (addHelper with $methods, it will throw exception in callHelper) 93 | * @expectedException Pix_Helper_Exception 94 | */ 95 | public function testNotPixHelperHelperClass2() 96 | { 97 | $manager = new Pix_Helper_Manager(); 98 | $manager->addHelper('Pix_Helper_HelperTest_NotPixHelper', array('test')); 99 | $manager->callHelper('test', array()); 100 | } 101 | 102 | 103 | /** 104 | * test invalid method in addHelper 105 | * @expectedException Pix_Helper_Exception 106 | */ 107 | public function testInvalidMethodsInAddHelper() 108 | { 109 | $manager = new Pix_Helper_Manager(); 110 | $manager->addHelper('Pix_Helper_HelperTest_Helper1', 'must array'); 111 | } 112 | 113 | /** 114 | * test call method is not exists 115 | * @expectedException Pix_Helper_Exception 116 | */ 117 | public function testCallMethodIsNotExists() 118 | { 119 | $manager = new Pix_Helper_Manager(); 120 | $manager->callHelper('notExists', array()); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /webdata/scripts/update-data.php: -------------------------------------------------------------------------------- 1 | loadHTML(file_get_contents("http://ronnywang-twcompany.s3-website-ap-northeast-1.amazonaws.com/index.html")); 8 | 9 | $time = null; 10 | foreach ($doc->getElementsByTagName('tr') as $tr_dom) { 11 | $td_doms = $tr_dom->getElementsByTagName('td'); 12 | if ($td_doms->item(0)->nodeValue == 'files/') { 13 | $time = strtotime($td_doms->item(1)->nodeValue); 14 | } 15 | } 16 | return $time; 17 | }; 18 | 19 | $old_data_time = KeyValue::get('data_updated_at'); 20 | 21 | $new_data_time = $get_online_data_time(); 22 | if (is_null($new_data_time) or $new_data_time <= $old_data_time) { 23 | error_log("skip"); 24 | exit; 25 | } 26 | 27 | mkdir("/tmp/company-graph-data"); 28 | for ($i = 0; $i < 10; $i ++) { 29 | system("wget -O /tmp/company-graph-data/{$i}.gz http://ronnywang-twcompany.s3-website-ap-northeast-1.amazonaws.com/files/{$i}0000000.jsonl.gz"); 30 | } 31 | 32 | $output = fopen('/tmp/company-graph-data/graph.csv', 'w'); 33 | for ($i = 0; $i < 10; $i ++) { 34 | $fp = gzopen("/tmp/company-graph-data/{$i}.gz", 'r'); 35 | while ($line = fgets($fp)) { 36 | $obj = json_decode($line); 37 | $showed = array(); 38 | if (!$obj or !property_exists($obj, '董監事名單')) { 39 | continue; 40 | } 41 | 42 | $main_id = $obj->id; 43 | foreach ($obj->{'董監事名單'} as $record) { 44 | if (!$record->{'所代表法人'}) { 45 | continue; 46 | } 47 | if ($record->{'所代表法人'}[0]) { 48 | $board_type = 'id'; 49 | $value = $record->{'所代表法人'}[0]; 50 | } else { 51 | $board_type = 'name'; 52 | $value = $record->{'所代表法人'}[1]; 53 | } 54 | 55 | if (!$record->{'出資額'}) { 56 | continue; 57 | } 58 | $id = $main_id . $board_type . $value; 59 | if (array_key_exists($id, $showed)) { 60 | continue; 61 | } 62 | $showed[$id] = true; 63 | 64 | 65 | fputcsv($output, array( 66 | $main_id, 67 | $board_type, 68 | $value, 69 | '', 70 | str_replace(',', '', $record->{'出資額'}), 71 | )); 72 | } 73 | } 74 | fclose($fp); 75 | } 76 | fclose($output); 77 | 78 | $fp = fopen('/tmp/company-graph-data/graph.csv', 'r'); 79 | 80 | $db = CompanyGraph::getDb(); 81 | 82 | try { 83 | $sql = "DROP TABLE company_graph_tmp"; 84 | $db->query($sql); 85 | } catch (Exception $e) { 86 | } 87 | 88 | $sql = "CREATE TABLE company_graph_tmp LIKE company_graph"; 89 | $db->query($sql); 90 | 91 | $terms = array(); 92 | while ($row = fgetcsv($fp)) { 93 | list($company_id, $board_type, $board_value,, $amount) = $row; 94 | 95 | $terms[] = sprintf("(%d,%d,%d,'',%d)", 96 | intval($company_id), 97 | ('name' == $board_type) ? 1 : 0, 98 | ('name' == $board_type) ? crc32($board_value) : $board_value, 99 | intval($amount) 100 | ); 101 | 102 | if (count($terms) >= 5000) { 103 | $sql = "INSERT INTO company_graph_tmp (company_id, board_type, board_id, board_name, amount) VALUES " . implode(',', $terms); 104 | $db->query($sql); 105 | $terms = array(); 106 | } 107 | } 108 | fclose($fp); 109 | 110 | if (count($terms)) { 111 | $sql = "INSERT INTO company_graph_tmp (company_id, board_type, board_id, board_name, amount) VALUES " . implode(',', $terms); 112 | $db->query($sql); 113 | $terms = array(); 114 | } 115 | try { 116 | $db->query("DROP TABLE company_graph_old"); 117 | } catch (Exception $e) { 118 | } 119 | 120 | // 如果同一個月的話,就直接砍掉舊的,表示可能是抓到一半 121 | if (!$old_data_time or date('Ym', $old_data_time) == date('Ym', $new_data_time)) { 122 | $db->query("RENAME TABLE company_graph TO company_graph_old"); 123 | $db->query("RENAME TABLE company_graph_tmp TO company_graph"); 124 | } else { 125 | $db->query("RENAME TABLE company_graph TO company_graph_" . date('Ym', $old_data_time)); 126 | $db->query("RENAME TABLE company_graph_tmp TO company_graph"); 127 | } 128 | KeyValue::set('data_updated_at', $new_data_time); 129 | 130 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Table/Db/Adapter/PixCache.php: -------------------------------------------------------------------------------- 1 | _cache = $cache; 19 | $this->_prefix = $prefix; 20 | } 21 | 22 | /** 23 | * createTable 將 $table 建立進資料庫內 24 | * 25 | * @param Pix_Table $table 26 | * @access public 27 | * @return void 28 | */ 29 | public function createTable($table) 30 | { 31 | } 32 | 33 | /** 34 | * dropTable 從資料庫內移除 $table 這個 Table 35 | * 36 | * @param Pix_Table $table 37 | * @access public 38 | * @return void 39 | */ 40 | public function dropTable($table) 41 | { 42 | } 43 | 44 | protected function getKey($primary_values) 45 | { 46 | $keys = array(); 47 | foreach ($primary_values as $v) { 48 | $keys[] = urlencode($v); 49 | } 50 | $key = $this->_prefix . implode('&', $keys); 51 | return $key; 52 | } 53 | 54 | public function fetchOne($table, $primary_values) 55 | { 56 | $c = $this->_cache; 57 | 58 | $keys = array(); 59 | foreach ($table->_columns as $col => $col_options) { 60 | // PK 不用抓 61 | if (in_array($col, $table->getPrimaryColumns())) { 62 | continue; 63 | } 64 | $keys[] = $this->getKey($primary_values) . ':' . $col; 65 | } 66 | 67 | if (!$values = $c->gets($keys)) { 68 | return null; 69 | } 70 | 71 | $return_values = array_combine($table->getPrimaryColumns(), $primary_values); 72 | foreach ($table->_columns as $col => $col_options) { 73 | // PK 不用抓 74 | if (in_array($col, $table->getPrimaryColumns())) { 75 | continue; 76 | } 77 | $return_values[$col] = $values[$this->getKey($primary_values) . ':' . $col]; 78 | } 79 | 80 | return $return_values; 81 | } 82 | 83 | public function deleteOne($row) 84 | { 85 | $table = $row->getTable(); 86 | $c = $this->_cache; 87 | foreach ($table->_columns as $col => $col_options) { 88 | // PK 不用抓 89 | if (in_array($col, $table->getPrimaryColumns())) { 90 | continue; 91 | } 92 | $c->delete($this->getKey($row->getPrimaryValues()) . ':' . $col); 93 | } 94 | } 95 | 96 | public function updateOne($row, $data) 97 | { 98 | $c = $this->_cache; 99 | if (!is_array($data)) { 100 | throw new Exception('must array'); 101 | } 102 | $table = $row->getTable(); 103 | $update_keys_values = array(); 104 | foreach ($data as $key => $value) { 105 | if (!$table->_columns[$key]) { 106 | throw new Exception($table->getClass() . " column {$key} not found"); 107 | } 108 | // PK 不用抓 109 | if (in_array($key, $table->getPrimaryColumns())) { 110 | continue; 111 | } 112 | $update_keys_values[$this->getKey($row->getPrimaryValues()) . ':' . $key] = $value; 113 | } 114 | $c->sets($update_keys_values); 115 | } 116 | 117 | public function insertOne($table, $keys_values) 118 | { 119 | $c = $this->_cache; 120 | $row = $table->createRow(); 121 | foreach ($keys_values as $k => $v) { 122 | $row->{$k} = $v; 123 | } 124 | $update_keys_values = array(); 125 | foreach ($row->toArray() as $key => $value) { 126 | if (!$table->_columns[$key]) { 127 | throw new Exception("column {$key} not found"); 128 | } 129 | if (in_array($key, $table->getPrimaryColumns())) { 130 | continue; 131 | } 132 | $update_keys_values[$this->getKey($row->findPrimaryValues()) . ':' . $key] = $value; 133 | } 134 | $c->sets($update_keys_values); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/coverage/Array_Filter.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Pix Framework 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 38 | 39 | 40 | 41 | 42 |
Pix Framework
17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 35 | 36 |
Current directory:/big/home/users/srwang/work/pixframework/Pix/Array/Filter
Legend: 25 | 26 | Low: 0% to 35% 27 | 28 | 29 | Medium: 35% to 70% 30 | 31 | 32 | High: 70% to 100% 33 | 34 |
37 |
43 | 44 |
45 | 46 |
47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 67 | 68 | 69 | 76 | 77 | 78 | 85 | 86 | 87 | 88 | 89 | 90 |
 Coverage
 LinesFunctions / MethodsClasses
Row.php 61 | 62 | 63 | 64 | 65 |
0.00%0.00%
66 |
0.00%0 / 3 70 | 71 | 72 | 73 | 74 |
0.00%0.00%
75 |
0.00%0 / 1 79 | 80 | 81 | 82 | 83 |
0.00%0.00%
84 |
0.00%0 / 1
91 |
92 | 93 |
94 | 95 | 96 | 97 | 98 |
Generated by PHPUnit 3.4.15 and Xdebug 2.1.3 using PHP 5.3.10 at Tue Apr 24 16:09:33 CST 2012.
99 | 100 |
101 | 102 | 103 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/coverage/Table_Search.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Pix Framework 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 38 | 39 | 40 | 41 | 42 |
Pix Framework
17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 35 | 36 |
Current directory:/big/home/users/srwang/work/pixframework/Pix/Table/Search
Legend: 25 | 26 | Low: 0% to 35% 27 | 28 | 29 | Medium: 35% to 70% 30 | 31 | 32 | High: 70% to 100% 33 | 34 |
37 |
43 | 44 |
45 | 46 |
47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 67 | 68 | 69 | 76 | 77 | 78 | 85 | 86 | 87 | 88 | 89 | 90 |
 Coverage
 LinesFunctions / MethodsClasses
Exception.php 61 | 62 | 63 | 64 | 65 |
0.00%0.00%
66 |
0.00%0 / 1 70 | 71 | 72 | 73 | 74 |
  
75 |
   79 | 80 | 81 | 82 | 83 |
0.00%0.00%
84 |
0.00%0 / 1
91 |
92 | 93 |
94 | 95 | 96 | 97 | 98 |
Generated by PHPUnit 3.4.15 and Xdebug 2.1.3 using PHP 5.3.10 at Tue Apr 24 16:09:33 CST 2012.
99 | 100 |
101 | 102 | 103 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Cache/Adapter/Memcached.php: -------------------------------------------------------------------------------- 1 | array( ... ), ...) 格式 22 | $this->_servers = $config['servers']; 23 | } elseif (is_array($config[0])) { // array(array('host' => ...), array('host' => ...) ... ) 24 | $this->_servers = $config; 25 | } else { // array('host' => ...) 26 | $this->_servers = array($config); 27 | } 28 | 29 | if (isset($config['options'])) { 30 | if (isset($config['options']['expire'])) { 31 | $this->_default_expire = $config['options']['expire']; 32 | } 33 | if (isset($config['options']['compress'])) { 34 | $this->_default_compress = $config['options']['compress']; 35 | } 36 | } 37 | } 38 | 39 | public function getMemcache() 40 | { 41 | if (is_null($this->_memcache)) { 42 | $servers = $this->_servers; 43 | if (!is_array($servers)) { 44 | throw new Pix_Exception('config error'); 45 | } 46 | 47 | $this->_memcache = new Memcached; 48 | foreach ($servers as $server) { 49 | $this->_memcache->addServer( 50 | $server['host'], 51 | $server['port'], 52 | isset($server['weight']) ? intval($server['weight']) : 1 53 | ); 54 | } 55 | } 56 | return $this->_memcache; 57 | } 58 | 59 | protected function _getOptions($options) 60 | { 61 | $ret = array(); 62 | $ret['expire'] = is_int($options) ? $options : (isset($options['expire']) ? $options['expire'] : $this->_default_expire); 63 | $ret['compress'] = isset($options['compress']) ? $options['compress'] : $this->_default_compress; 64 | return $ret; 65 | } 66 | 67 | public function add($key, $value, $options = array()) 68 | { 69 | $memcache = $this->getMemcache(); 70 | $options = $this->_getOptions($options); 71 | $memcache->setOption(Memcached::OPT_COMPRESSION, $options['compress'] ? true : false); 72 | return $memcache->add($key, $value, $options['expire']); 73 | } 74 | 75 | public function set($key, $value, $options = array()) 76 | { 77 | $memcache = $this->getMemcache(); 78 | $options = $this->_getOptions($options); 79 | $memcache->setOption(Memcached::OPT_COMPRESSION, $options['compress'] ? true : false); 80 | return $memcache->set($key, $value, $options['expire']); 81 | } 82 | 83 | public function delete($key) 84 | { 85 | $memcache = $this->getMemcache(); 86 | return $memcache->delete($key, 0); 87 | } 88 | 89 | public function replace($key, $value, $options = array()) 90 | { 91 | $memcache = $this->getMemcache(); 92 | $options = $this->_getOptions($options); 93 | $memcache->setOption(Memcached::OPT_COMPRESSION, $options['compress'] ? true : false); 94 | return $memcache->replace($key, $value, $options['expire']); 95 | } 96 | 97 | public function inc($key, $inc = 1) 98 | { 99 | $memcache = $this->getMemcache(); 100 | return $memcache->increment($key, $inc); 101 | } 102 | 103 | public function dec($key, $inc = 1) 104 | { 105 | $memcache = $this->getMemcache(); 106 | return $memcache->decrement($key, $inc); 107 | } 108 | 109 | public function append($key, $data, $options = array()) 110 | { 111 | $memcache = $this->getMemcache(); 112 | $options = $this->_getOptions($options); 113 | return $memcache->append($key, $data); 114 | } 115 | 116 | public function prepend($key, $data, $options = array()) 117 | { 118 | $memcache = $this->getMemcache(); 119 | $options = $this->_getOptions($options); 120 | return $memcache->prepend($key, $data); 121 | } 122 | 123 | public function get($key) 124 | { 125 | $memcache = $this->getMemcache(); 126 | return $memcache->get($key); 127 | } 128 | 129 | public function gets($keys) 130 | { 131 | $memcache = $this->getMemcache(); 132 | return $memcache->getMulti($keys); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/coverage/Table_Db_Adapter_PDO.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Pix Framework 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 38 | 39 | 40 | 41 | 42 |
Pix Framework
17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 35 | 36 |
Current directory:/big/home/users/srwang/work/pixframework/Pix/Table/Db/Adapter/PDO
Legend: 25 | 26 | Low: 0% to 35% 27 | 28 | 29 | Medium: 35% to 70% 30 | 31 | 32 | High: 70% to 100% 33 | 34 |
37 |
43 | 44 |
45 | 46 |
47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 67 | 68 | 69 | 76 | 77 | 78 | 85 | 86 | 87 | 88 | 89 | 90 |
 Coverage
 LinesFunctions / MethodsClasses
Result.php 61 | 62 | 63 | 64 | 65 |
0.00%0.00%
66 |
0.00%0 / 8 70 | 71 | 72 | 73 | 74 |
0.00%0.00%
75 |
0.00%0 / 4 79 | 80 | 81 | 82 | 83 |
0.00%0.00%
84 |
0.00%0 / 1
91 |
92 | 93 |
94 | 95 | 96 | 97 | 98 |
Generated by PHPUnit 3.4.15 and Xdebug 2.1.3 using PHP 5.3.10 at Tue Apr 24 16:09:33 CST 2012.
99 | 100 |
101 | 102 | 103 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/tests/Pix/Table/TableCacheTest.php: -------------------------------------------------------------------------------- 1 | _name = 'user'; 8 | $this->_primary = 'id'; 9 | 10 | $this->_columns['id'] = array('type' => 'int', 'auto_increment' => true); 11 | $this->_columns['name'] = array('type' => 'varchar', 'size' => 32); 12 | $this->_columns['password'] = array('type' => 'varchar', 'size' => 32, 'default' => ''); 13 | } 14 | } 15 | 16 | class Pix_Table_TableCacheTest_Cache extends Pix_Cache 17 | { 18 | protected $_data = array(); 19 | 20 | public function load($key) 21 | { 22 | // Pix_Cache 如果沒有 cache 資料是會傳 false 23 | if (array_key_exists($key, $this->_data)) { 24 | return $this->_data[$key]; 25 | } 26 | return false; 27 | } 28 | 29 | public function save($key, $value) 30 | { 31 | $this->_data[$key] = $value; 32 | } 33 | 34 | public function delete($key) 35 | { 36 | unset($this->_data[$key]); 37 | } 38 | } 39 | 40 | class Pix_Table_TableCacheTest extends PHPUnit_Framework_TestCase 41 | { 42 | protected $_old_cache; 43 | protected $_old_save_memory; 44 | 45 | public function setUp() 46 | { 47 | $this->_old_cache = Pix_Table::getCache(); 48 | $this->_old_save_memory = Pix_Table::$_save_memory; 49 | } 50 | 51 | public function tearDown() 52 | { 53 | Pix_Table::setCache($this->_old_cache); 54 | Pix_Table::$_save_memory = $this->_old_save_memory; 55 | } 56 | 57 | public function testDisableCache() 58 | { 59 | Pix_Table::$_save_memory = true; 60 | 61 | $cache = $this->getMock('Pix_Cache', array('load')); 62 | $cache->expects($this->never()) 63 | ->method('load'); 64 | Pix_Table::setCache($cache); 65 | 66 | $table = Pix_Table::getTable('Pix_Table_TableCacheTest_User'); 67 | $table->disableTableCache(); 68 | $this->assertEquals($table->getRowFromCache(array(1)), false); 69 | } 70 | 71 | public function testEnableCacheSaveMemory() 72 | { 73 | Pix_Table::$_save_memory = true; 74 | 75 | $cache = new Pix_Table_TableCacheTest_Cache; 76 | Pix_Table::setCache($cache); 77 | 78 | $table = Pix_Table::getTable('Pix_Table_TableCacheTest_User'); 79 | $table->enableTableCache(); 80 | 81 | $table->cacheRow(1, array('id' => 1, 'name' => 'abc', 'password' => 'def')); 82 | 83 | $row = $table->getRowFromCache(1); 84 | $this->assertEquals($row->id, 1); 85 | $this->assertEquals($row->name, 'abc'); 86 | $this->assertEquals($row->password, 'def'); 87 | } 88 | 89 | public function testNullOrFalseSaveMemory() 90 | { 91 | Pix_Table::$_save_memory = true; 92 | 93 | $cache = new Pix_Table_TableCacheTest_Cache; 94 | Pix_Table::setCache($cache); 95 | 96 | $table = Pix_Table::getTable('Pix_Table_TableCacheTest_User'); 97 | $table->enableTableCache(); 98 | 99 | // 什麼都沒有是 false 100 | $this->assertTrue($table->getRowFromCache(2) === false); 101 | // cacheRow null 後是 null (表示被刪除) 102 | $table->cacheRow(3, null); 103 | $this->assertTrue($table->getRowFromCache(3) === null); 104 | // cacheRow false 後是 false 105 | $table->cacheRow(4, false); 106 | $this->assertTrue($table->getRowFromCache(4) === false); 107 | } 108 | 109 | public function testEnableCache() 110 | { 111 | Pix_Table::$_save_memory = false; 112 | 113 | $cache = new Pix_Table_TableCacheTest_Cache; 114 | Pix_Table::setCache($cache); 115 | 116 | $table = Pix_Table::getTable('Pix_Table_TableCacheTest_User'); 117 | $table->enableTableCache(); 118 | 119 | $table->cacheRow(5, array('id' => 5, 'name' => 'abc', 'password' => 'def')); 120 | 121 | $row = $table->getRowFromCache(5); 122 | $this->assertEquals($row->id, 5); 123 | $this->assertEquals($row->name, 'abc'); 124 | $this->assertEquals($row->password, 'def'); 125 | } 126 | 127 | public function testNullOrFalse() 128 | { 129 | Pix_Table::$_save_memory = false; 130 | 131 | $cache = new Pix_Table_TableCacheTest_Cache; 132 | Pix_Table::setCache($cache); 133 | 134 | $table = Pix_Table::getTable('Pix_Table_TableCacheTest_User'); 135 | $table->enableTableCache(); 136 | 137 | // 什麼都沒有是 false 138 | $this->assertTrue($table->getRowFromCache(6) === false); 139 | // cacheRow null 後是 null (表示被刪除) 140 | $table->cacheRow(7, null); 141 | $this->assertTrue($table->getRowFromCache(7) === null); 142 | // cacheRow false 後是 false 143 | $table->cacheRow(8, false); 144 | $this->assertTrue($table->getRowFromCache(8) === false); 145 | } 146 | 147 | } 148 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Cache/Adapter/Memcache.php: -------------------------------------------------------------------------------- 1 | array( ... ), ...) 格式 22 | $this->_servers = $config['servers']; 23 | } elseif (is_array($config[0])) { // array(array('host' => ...), array('host' => ...) ... ) 24 | $this->_servers = $config; 25 | } else { // array('host' => ...) 26 | $this->_servers = array($config); 27 | } 28 | 29 | if (isset($config['options'])) { 30 | if (isset($config['options']['expire'])) { 31 | $this->_default_expire = $config['options']['expire']; 32 | } 33 | if (isset($config['options']['compress'])) { 34 | $this->_default_compress = $config['options']['compress']; 35 | } 36 | } 37 | } 38 | 39 | public function getMemcache() 40 | { 41 | if (is_null($this->_memcache)) { 42 | $servers = $this->_servers; 43 | if (!is_array($servers)) { 44 | throw new Pix_Exception('config error'); 45 | } 46 | 47 | $this->_memcache = new Memcache; 48 | foreach ($servers as $server) { 49 | $this->_memcache->addServer( 50 | $server['host'], 51 | $server['port'], 52 | true, 53 | isset($server['weight']) ? intval($server['weight']) : 1, 54 | 10 55 | ); 56 | } 57 | } 58 | return $this->_memcache; 59 | } 60 | 61 | protected function _getOptions($options) 62 | { 63 | $ret = array(); 64 | $ret['expire'] = is_int($options) ? $options : (isset($options['expire']) ? $options['expire'] : $this->_default_expire); 65 | $ret['compress'] = isset($options['compress']) ? $options['compress'] : $this->_default_compress; 66 | return $ret; 67 | } 68 | 69 | public function add($key, $value, $options = array()) 70 | { 71 | $memcache = $this->getMemcache(); 72 | $options = $this->_getOptions($options); 73 | return $memcache->add($key, $value, $options['compress'] ? MEMCACHE_COMPRESSED : false, $options['expire']); 74 | } 75 | 76 | public function set($key, $value, $options = array()) 77 | { 78 | $memcache = $this->getMemcache(); 79 | $options = $this->_getOptions($options); 80 | return $memcache->set($key, $value, $options['compress'] ? MEMCACHE_COMPRESSED : false, $options['expire']); 81 | } 82 | 83 | public function delete($key) 84 | { 85 | $memcache = $this->getMemcache(); 86 | return $memcache->delete($key, 0); 87 | } 88 | 89 | public function replace($key, $value, $options = array()) 90 | { 91 | $memcache = $this->getMemcache(); 92 | $options = $this->_getOptions($options); 93 | return $memcache->replace($key, $value, $options['compress'] ? MEMCACHE_COMPRESSED : false, $options['expire']); 94 | } 95 | 96 | public function inc($key, $inc = 1) 97 | { 98 | $memcache = $this->getMemcache(); 99 | return $memcache->increment($key, $inc); 100 | } 101 | 102 | public function dec($key, $inc = 1) 103 | { 104 | $memcache = $this->getMemcache(); 105 | return $memcache->decrement($key, $inc); 106 | } 107 | 108 | public function append($key, $data, $options = array()) 109 | { 110 | $memcache = $this->getMemcache(); 111 | $options = $this->_getOptions($options); 112 | return $memcache->set($key, $memcache->get($key) . $data, $options['compress'] ? MEMCACHE_COMPRESSED : false, $options['expire']); 113 | } 114 | 115 | public function prepend($key, $data, $options = array()) 116 | { 117 | $memcache = $this->getMemcache(); 118 | $options = $this->_getOptions($options); 119 | return $memcache->set($key, $data . $memcache->get($key), $options['compress'] ? MEMCACHE_COMPRESSED : false, $options['expire']); 120 | } 121 | 122 | public function get($key) 123 | { 124 | $memcache = $this->getMemcache(); 125 | return $memcache->get($key); 126 | } 127 | 128 | public function gets(array $keys) 129 | { 130 | $memcache = $this->getMemcache(); 131 | return $memcache->get($keys); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Helper/Manager.php: -------------------------------------------------------------------------------- 1 | getFuncs()) 22 | * @param array|null $options helper options 23 | * @access public 24 | * @return void 25 | */ 26 | public function addHelper($helper, $methods = null, $options = null) 27 | { 28 | if (!is_scalar($helper)) { 29 | throw new Pix_Helper_Exception('Helper name must be string'); 30 | } 31 | 32 | if (is_null($methods)) { 33 | if (!class_exists($helper)) { 34 | throw new Pix_Helper_Exception("{$helper} is not a class"); 35 | } 36 | 37 | if (!is_scalar($helper) or !is_subclass_of($helper, 'Pix_Helper')) { 38 | throw new Pix_Helper_Exception("{$helper} is not a Pix_Helper"); 39 | } 40 | 41 | $methods = call_user_func(array($helper, 'getFuncs')); 42 | } 43 | 44 | if (!is_array($methods)) { 45 | throw new Pix_Helper_Exception("Pix_Helper::addHelper() expects parameter 3 to be array, " . gettype($methods) . " given"); 46 | } 47 | 48 | $id = array_push($this->_helper_infos, array( 49 | 'helper' => $helper, 50 | 'options' => $options 51 | )) - 1; 52 | 53 | foreach ($methods as $method) { 54 | if ('*' == $method) { 55 | $this->_wildcard_helpers[] = $id; 56 | } else { 57 | $this->_method_to_helper_map[strtolower($method)] = $id; 58 | } 59 | } 60 | } 61 | 62 | /** 63 | * getMethods get all method names in this helper manager 64 | * 65 | * @access public 66 | * @return array method names (lower case) 67 | */ 68 | public function getMethods() 69 | { 70 | // TODO: wildcard helper support 71 | return array_keys($this->_method_to_helper_map); 72 | } 73 | 74 | /** 75 | * hasMethod check if method is in this manager 76 | * 77 | * @param string $method method name (case insensitive) 78 | * @access public 79 | * @return boolean 80 | */ 81 | public function hasMethod($method) 82 | { 83 | return !is_null($this->_getHelperIdByMethodName($method)); 84 | } 85 | 86 | /** 87 | * _getHelperIdByMethodName get Helper ID by method name 88 | * 89 | * @param string $method 90 | * @access protected 91 | * @return null-not found, int-helper id 92 | */ 93 | protected function _getHelperIdByMethodName($method) 94 | { 95 | if (array_key_exists(strtolower($method), $this->_method_to_helper_map)) { 96 | return $this->_method_to_helper_map[strtolower($method)]; 97 | } 98 | 99 | foreach ($this->_wildcard_helpers as $helper_id) { 100 | $helper_info = $this->_getHelperInfo($helper_id); 101 | if ($helper_info['object']->hasMethod($method)) { 102 | $this->_method_to_helper_map[strtolower($method)] = $helper_id; 103 | return $helper_id; 104 | } 105 | } 106 | 107 | return null; 108 | } 109 | 110 | /** 111 | * _getHelperInfo get Helper info by Id 112 | * 113 | * @param int $helper_id 114 | * @access protected 115 | * @return array array(object-helper object, helper-helper class name, options-helper options) 116 | */ 117 | protected function _getHelperInfo($helper_id) 118 | { 119 | $helper_info = $this->_helper_infos[$helper_id]; 120 | 121 | if (!array_key_exists('object', $helper_info)) { 122 | $helper = $helper_info['helper']; 123 | 124 | if (!class_exists($helper)) { 125 | throw new Pix_Helper_Exception("{$helper} is not a class"); 126 | } 127 | 128 | if (!is_scalar($helper) or !is_subclass_of($helper, 'Pix_Helper')) { 129 | throw new Pix_Helper_Exception("{$helper} is not a Pix_Helper"); 130 | } 131 | 132 | $helper_info['object'] = new $helper($helper_info['options']); 133 | $this->_helper_infos[$helper_id] = $helper_info; 134 | } 135 | 136 | return $helper_info; 137 | } 138 | 139 | /** 140 | * callHelper call a helper method 141 | * 142 | * @param string $method method name (case insensitive) 143 | * @param array $args arguments 144 | * @access public 145 | * @return mixed helper method return value 146 | */ 147 | public function callHelper($method, $args) 148 | { 149 | $helper_id = $this->_getHelperIdByMethodName($method); 150 | if (is_null($helper_id)) { 151 | throw new Pix_Helper_Exception("There is no {$method} in Helper"); 152 | } 153 | $helper_info = $this->_getHelperInfo($helper_id); 154 | 155 | return call_user_func_array(array($helper_info['object'], $method), $args); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Array.php: -------------------------------------------------------------------------------- 1 | 17 | */ 18 | abstract class Pix_Array implements Countable, SeekableIterator, ArrayAccess 19 | { 20 | protected $_filters = array(); 21 | 22 | /** 23 | * factory 24 | * 建立一個 Pix_Array array ,可以傳 Pix_Array Object 進去 or Array 25 | * 26 | * @param mixed $obj 27 | * @static 28 | * @access public 29 | * @return void 30 | */ 31 | public static function factory($obj = null) 32 | { 33 | if (is_object($obj) and is_a($obj, 'Pix_Array')) { 34 | return $obj; 35 | } 36 | 37 | if (is_array($obj)) { 38 | return new Pix_Array_Array($obj); 39 | } 40 | 41 | if (is_null($obj)) { 42 | return new Pix_Array_Array(array()); 43 | } 44 | return null; 45 | } 46 | 47 | /** 48 | * getRand 回傳這個 Pix_Array 中最多 $num 個的隨機物品 49 | * $num 為 0 表示只回傳一樣東西 50 | * 51 | * @param int $num 52 | * @abstract 53 | * @access public 54 | * @return Pix_Array 55 | */ 56 | abstract public function getRand($num = null); 57 | abstract public function offset(); 58 | abstract public function order(); 59 | abstract public function limit(); 60 | abstract public function sum($column = null); 61 | abstract public function max($column = null); 62 | abstract public function min($column = null); 63 | abstract public function first(); 64 | abstract public function toArray($column = null); 65 | abstract public function getPosition($obj); 66 | 67 | // XXX: 需要檢查所有繼承 Pix_Array 的 class,並 implement 這五個 function 68 | public function push($value) 69 | { 70 | throw new Pix_Array_Exception('尚未實做'); 71 | } 72 | 73 | public function pop() 74 | { 75 | throw new Pix_Array_Exception('尚未實做'); 76 | } 77 | 78 | public function shift() 79 | { 80 | throw new Pix_Array_Exception('尚未實做'); 81 | } 82 | 83 | public function unshift($value) 84 | { 85 | throw new Pix_Array_Exception('尚未實做'); 86 | } 87 | 88 | public function reverse($preserve_keys = false) 89 | { 90 | throw new Pix_Array_Exception('尚未實做'); 91 | } 92 | 93 | public function pager($page, $perPage) 94 | { 95 | $page = max(1, intval($page)); 96 | return $this->limit($perPage)->offset(($page - 1) * $perPage); 97 | } 98 | 99 | public function paginate($page = 1, $options = array()) 100 | { 101 | $default_per_page = 20; 102 | $page = max(1, intval($page)); 103 | $default_settings = array( 104 | // per_page:每頁幾項, order:SQL排序QUERY 105 | 'per_page' => $default_per_page, 106 | 'order' => '`id` DESC', 107 | ); 108 | $settings = array_merge($default_settings, $options); 109 | foreach ($settings as $key => $val) { 110 | $$key = $val; 111 | } 112 | if ($per_page <= 0) $per_page = $default_per_page; 113 | $this->total_page = ceil(count($this) / $per_page); 114 | $this->per_page = $per_page; 115 | $this->now_page = $page; 116 | return $this->limit($per_page)->offset(($page - 1) * $per_page)->order($order); 117 | } 118 | 119 | public function filter($filter, $options = array()) 120 | { 121 | $obj = clone $this; 122 | $obj->addFilter($filter, $options); 123 | return $obj; 124 | } 125 | 126 | public function filterBuiltIn($filter, $options = array()) 127 | { 128 | $obj = clone $this; 129 | $filter_name = 'Pix_Array_Filter_' . $filter; 130 | $filter_obj = new $filter_name; 131 | $obj->addFilter(array($filter_obj, 'filter'), $options); 132 | return $obj; 133 | } 134 | 135 | protected function addFilter($filter, $options) 136 | { 137 | $this->_filters[] = array($filter, $options); 138 | } 139 | 140 | protected $_after; 141 | protected $_after_included = false; 142 | 143 | public function after() 144 | { 145 | $args = func_get_args(); 146 | if (!count($args)) { 147 | return $this->_after; 148 | } 149 | $rs = clone $this; 150 | $rs->_after = $args[0]; 151 | $rs->_after_included = array_key_exists(1, $args) ? $args[1] : false; 152 | return $rs; 153 | } 154 | 155 | protected function filterRow() 156 | { 157 | if ($this->_after) { 158 | $compare = $this->_sort($this->current(), $this->_after); 159 | 160 | if ($compare < 0) { 161 | return false; 162 | } 163 | 164 | if ($compare == 0 and !$this->_after_included) { 165 | return false; 166 | } 167 | } 168 | 169 | if (count($this->_filters)) { 170 | foreach ($this->_filters as $filter) { 171 | list($callback, $options) = $filter; 172 | if (is_callable($callback)) { 173 | return call_user_func_array($callback, array($this->current(), $options)); 174 | } 175 | } 176 | } 177 | return TRUE; 178 | } 179 | 180 | protected function getFilters() 181 | { 182 | return $this->_filters; 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Partial/Helper/JQueryTmpl.php: -------------------------------------------------------------------------------- 1 | {$term}; 127 | } 128 | } 129 | return htmlspecialchars($t); 130 | } 131 | 132 | protected function _walkToken($tokens, $start, $end, $data) 133 | { 134 | for ($i = $start; $i < $end; $i ++) { 135 | $token = $tokens[$i]; 136 | if ($token['type'] == 'text') { 137 | echo $token['text']; 138 | continue; 139 | } 140 | 141 | if ($token['type'] == 'variable') { 142 | echo $this->_printVariable($data, $token['variable']); 143 | continue; 144 | } 145 | 146 | if ($token['type'] == 'each') { 147 | foreach ($data->{$token['variable']} as $index => $value) { 148 | $new_data = clone $data; 149 | $new_data->{$token['each_index']} = $index; 150 | $new_data->{$token['each_value']} = $value; 151 | $this->_walkToken($tokens, $i + 1, $token['match'], $new_data); 152 | unset($new_data); 153 | } 154 | $i = $token['match']; 155 | continue; 156 | } 157 | } 158 | } 159 | 160 | public function jQueryTmpl($me, $path, $data) 161 | { 162 | $content = file_get_contents($me->getPath() . '/' . $path); 163 | $tokens = $this->_getTokens($content); 164 | 165 | $this->_walkToken($tokens, 0, count($tokens), $data); 166 | } 167 | 168 | public function addJQueryTmpl($me, $path, $id) 169 | { 170 | if ($me->getPath()) { 171 | $path = $me->getPath() . '/' . ltrim($path, '/'); 172 | } else { 173 | $path = $path; 174 | } 175 | ob_start(); 176 | echo ''; 179 | return ob_get_clean(); 180 | 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/tests/Pix/Table/TableHelperTest.php: -------------------------------------------------------------------------------- 1 | _value = $value; 10 | } 11 | 12 | public function getData() 13 | { 14 | return $this->_value; 15 | } 16 | } 17 | 18 | class Pix_Table_TableHelperTest_Table extends Pix_Table 19 | { 20 | public function init() 21 | { 22 | $this->_resultSetClass = 'Pix_Table_TableHelperTest_TableResultSet'; 23 | 24 | $this->_columns['id'] = array('type' => 'varchar', 'size' => 32); 25 | } 26 | 27 | protected static $_value; 28 | 29 | public static function setData($value) 30 | { 31 | self::$_value = $value; 32 | } 33 | 34 | public static function getData() 35 | { 36 | return self::$_value; 37 | } 38 | } 39 | 40 | class Pix_Table_TableHelperTest_Helper extends Pix_Helper 41 | { 42 | public function row_test($row, $value) 43 | { 44 | return 'RowHelper-' . $row->id . '-' . $value; 45 | } 46 | 47 | public function static_row_test($row, $value) 48 | { 49 | return 'StaticRowHelper-' . $row->id . '-' . $value; 50 | } 51 | 52 | public function resultset_test($resultset, $value) 53 | { 54 | return 'ResultSetHelper-' . $resultset->getData() . '-' . $value; 55 | } 56 | 57 | public function static_resultset_test($resultset, $value) 58 | { 59 | return 'StaticResultSetHelper-' . $resultset->getData() . '-' . $value; 60 | } 61 | 62 | public function table_test($table, $value) 63 | { 64 | return 'TableHelper-' . $table->getData() . '-' . $value; 65 | } 66 | 67 | public function static_table_test($table, $value) 68 | { 69 | return 'StaticTableHelper-' . $table->getData() . '-' . $value; 70 | } 71 | } 72 | 73 | class Pix_Table_TableHelperTest extends PHPUnit_Framework_TestCase 74 | { 75 | /** 76 | * Sets up the fixture, for example, opens a network connection. 77 | * This method is called before a test is executed. 78 | */ 79 | protected function setUp() 80 | { 81 | } 82 | 83 | /** 84 | * Tears down the fixture, for example, closes a network connection. 85 | * This method is called after a test is executed. 86 | */ 87 | protected function tearDown() 88 | { 89 | } 90 | 91 | /** 92 | * testRowHelper test add Row Helper in a Table 93 | */ 94 | public function testRowHelper() 95 | { 96 | Pix_Table_TableHelperTest_Table::addRowHelper('Pix_Table_TableHelperTest_Helper', array('row_test')); 97 | 98 | $row = Pix_Table_TableHelperTest_Table::createRow(); 99 | $row->id = uniqid(); 100 | $uniqid = uniqid(); 101 | $this->assertEquals($row->row_test($uniqid), 'RowHelper-' . $row->id . '-' . $uniqid); 102 | } 103 | 104 | /** 105 | * testStaticRowHelper test add Row Helper to all Pix_Table 106 | */ 107 | public function testStaticRowHelper() 108 | { 109 | Pix_Table::addStaticRowHelper('Pix_Table_TableHelperTest_Helper', array('static_row_test')); 110 | 111 | $row = Pix_Table_TableHelperTest_Table::createRow(); 112 | $row->id = uniqid(); 113 | $uniqid = uniqid(); 114 | $this->assertEquals($row->static_row_test($uniqid), 'StaticRowHelper-' . $row->id . '-' . $uniqid); 115 | } 116 | 117 | /** 118 | * testResultSetHelper test add ResultSet Helper in a Table 119 | */ 120 | public function testResultSetHelper() 121 | { 122 | Pix_Table_TableHelperTest_Table::addResultSetHelper('Pix_Table_TableHelperTest_Helper', array('resultset_test')); 123 | 124 | $resultset = Pix_Table_TableHelperTest_Table::search(1); 125 | $uniqid = uniqid(); 126 | $resultset->setData(uniqid()); 127 | $this->assertEquals($resultset->resultset_test($uniqid), 'ResultSetHelper-' . $resultset->getData() . '-' . $uniqid); 128 | } 129 | 130 | /** 131 | * testStaticResultSetHelper test add ResultSet Helper to all Pix_Table 132 | */ 133 | public function testStaticResultSetHelper() 134 | { 135 | Pix_Table::addStaticResultSetHelper('Pix_Table_TableHelperTest_Helper', array('static_resultset_test')); 136 | 137 | $resultset = Pix_Table_TableHelperTest_Table::search(1); 138 | $uniqid = uniqid(); 139 | $resultset->setData(uniqid()); 140 | $this->assertEquals($resultset->static_resultset_test($uniqid), 'StaticResultSetHelper-' . $resultset->getData() . '-' . $uniqid); 141 | } 142 | 143 | /** 144 | * testTableHelper test add Table Helper in a Table 145 | */ 146 | public function testTableHelper() 147 | { 148 | Pix_Table_TableHelperTest_Table::addTableHelper('Pix_Table_TableHelperTest_Helper', array('table_test')); 149 | 150 | Pix_Table_TableHelperTest_Table::setData(uniqid()); 151 | $uniqid = uniqid(); 152 | 153 | $this->assertEquals(Pix_Table_TableHelperTest_Table::table_test($uniqid), 'TableHelper-' . Pix_Table_TableHelperTest_Table::getData() . '-' . $uniqid); 154 | } 155 | 156 | /** 157 | * testStaticTableHelper test add Table Helper to all Pix_Table 158 | */ 159 | public function testStaticTableHelper() 160 | { 161 | Pix_Table::addStaticTableHelper('Pix_Table_TableHelperTest_Helper', array('static_table_test')); 162 | 163 | Pix_Table_TableHelperTest_Table::setData(uniqid()); 164 | $uniqid = uniqid(); 165 | 166 | $this->assertEquals(Pix_Table_TableHelperTest_Table::static_table_test($uniqid), 'StaticTableHelper-' . Pix_Table_TableHelperTest_Table::getData() . '-' . $uniqid); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Cache/Adapter/Array.php: -------------------------------------------------------------------------------- 1 | _big_array)) { 33 | return false; 34 | } 35 | 36 | self::set($key, $value, $options); 37 | return true; 38 | } 39 | 40 | /** 41 | * set 設定一筆 cache 42 | * 43 | * @param string $key 44 | * @param mixed $value 45 | * @param int|array $options 46 | * int: cache 過期的秒數, array(): 不會過期 47 | * @access public 48 | * @return bool 49 | */ 50 | public function set($key, $value, $options = array()) 51 | { 52 | if (array() === $options) { 53 | $this->_big_array[$key] = array('value' => $value); 54 | } elseif (is_numeric($options)) { 55 | $start_at = time(); 56 | $end_at = $start_at + (int)$options; 57 | $this->_big_array[$key] = array( 58 | 'value' => $value, 59 | 'start_at' => $start_at, 60 | 'end_at' => $end_at 61 | ); 62 | } 63 | 64 | return true; 65 | } 66 | 67 | /** 68 | * delete 刪除一筆 cache 69 | * 70 | * @param string $key 71 | * @access public 72 | * @return bool 73 | */ 74 | public function delete($key) 75 | { 76 | unset($this->_big_array[$key]); 77 | return true; 78 | } 79 | 80 | /** 81 | * replace 取代一筆 cache 82 | * 83 | * @param string $key 84 | * @param mixed $value 85 | * @param int|array $options 86 | * @access public 87 | * @return bool 如果 $key 不存在,就會回傳 false 88 | */ 89 | public function replace($key, $value, $options = array()) 90 | { 91 | if (!array_key_exists($key, $this->_big_array)) { 92 | return false; 93 | } 94 | 95 | self::set($key, $value, $options); 96 | return true; 97 | } 98 | 99 | /** 100 | * inc 對 cache 的值增加 $inc ,當原本的值不是數字時則視為 set() 101 | * 102 | * @param string $key 103 | * @param int $inc 104 | * @access public 105 | * @return bool 106 | */ 107 | public function inc($key, $inc = 1) 108 | { 109 | $old_value = self::get($key); 110 | if (!is_numeric($old_value)) { 111 | self::set($key, $inc); 112 | } else { 113 | $new_value = $old_value + $inc; 114 | self::set($key, $new_value); 115 | } 116 | 117 | return true; 118 | } 119 | 120 | /** 121 | * dec 對 cache 的值減少 $dec ,當原本的值不是數字時則視為 set() 122 | * 123 | * @param string $key 124 | * @param int $dec 125 | * @access public 126 | * @return bool 127 | */ 128 | public function dec($key, $dec = 1) 129 | { 130 | $old_value = self::get($key); 131 | if (!is_numeric($old_value)) { 132 | self::set($key, $dec); 133 | } else { 134 | $new_value = $old_value - $dec; 135 | self::set($key, $new_value); 136 | } 137 | 138 | return true; 139 | } 140 | 141 | /** 142 | * append 在 cache 的值後方加上 $data 143 | * 144 | * @param string $key 145 | * @param string $data 146 | * @param int|array $options 147 | * @access public 148 | * @return bool 當 $key 不存在時,則會回傳 false 149 | */ 150 | public function append($key, $data, $options = array()) 151 | { 152 | if (!is_scalar($data)) { 153 | throw new InvalidArgumentException('append 只能加文字'); 154 | } 155 | if (!array_key_exists($key, $this->_big_array)) { 156 | return false; 157 | } 158 | 159 | $data = strval($data); 160 | $old_value = self::get($key); 161 | $new_value = $old_value . $data; 162 | self::set($key, $new_value, $options); 163 | return true; 164 | } 165 | 166 | /** 167 | * prepend 在 cache 的值前方加上 $data 168 | * 169 | * @param string $key 170 | * @param string $data 171 | * @param int|array $options 172 | * @access public 173 | * @return bool 當 $key 不存在時,則會回傳 false 174 | */ 175 | public function prepend($key, $data, $options = array()) 176 | { 177 | if (!is_scalar($data)) { 178 | throw new InvalidArgumentException('prepend 只能加文字'); 179 | } 180 | if (!array_key_exists($key, $this->_big_array)) { 181 | return false; 182 | } 183 | 184 | $data = strval($data); 185 | $old_value = self::get($key); 186 | $new_value = $data . $old_value; 187 | self::set($key, $new_value, $options); 188 | return true; 189 | } 190 | 191 | /** 192 | * get 取得一筆 cache 193 | * 194 | * @param string $key 195 | * @access public 196 | * @return string 197 | */ 198 | public function get($key) 199 | { 200 | if (!array_key_exists($key, $this->_big_array)) { 201 | return false; 202 | } 203 | $result = $this->_big_array[$key]; 204 | if ($result['end_at'] && (time() > $result['end_at'])) { 205 | self::delete($key); 206 | } 207 | 208 | return $this->_big_array[$key]['value']; 209 | } 210 | 211 | /** 212 | * gets 取得多筆 cache 的值 213 | * 214 | * @param array $keys 215 | * @access public 216 | * @return array 217 | */ 218 | public function gets(array $keys) 219 | { 220 | $data = array(); 221 | foreach ($keys as $key) { 222 | $data[$key] = self::get($key); 223 | } 224 | return $data; 225 | } 226 | } 227 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/tests/Pix/Array/MergerTest.php: -------------------------------------------------------------------------------- 1 | order('age, name DESC') as $person) { 20 | $actual_result[] = $person['name']; 21 | } 22 | 23 | $excepted_result = array('fox', 'alice', 'bob', 'eva', 'david', 'carole'); 24 | $this->assertEquals($actual_result, $excepted_result); 25 | } 26 | 27 | public function testChunkSize() 28 | { 29 | $array = new Pix_Array_Merger(); 30 | $this->assertEquals($array->chunkSize(5)->chunkSize(), 5); 31 | $this->assertEquals($array->chunkSize(10)->chunkSize(), 10); 32 | } 33 | 34 | /** 35 | * @dataProvider arrayProvider 36 | */ 37 | public function testObjectOrder($array_male, $array_female) 38 | { 39 | // associate array to object array 40 | $array_male = Pix_Array::factory(json_decode(json_encode($array_male))); 41 | $array_female = Pix_Array::factory(json_decode(json_encode($array_female))); 42 | 43 | $array_merged = new Pix_Array_Merger($array_male, $array_female); 44 | 45 | $actual_result = array(); 46 | 47 | foreach ($array_merged->order('age, name DESC') as $key => $person) { 48 | $actual_result[] = $person->name; 49 | } 50 | 51 | $excepted_result = array('fox', 'alice', 'bob', 'eva', 'david', 'carole'); 52 | $this->assertEquals($actual_result, $excepted_result); 53 | } 54 | 55 | /** 56 | * @dataProvider arrayProvider 57 | */ 58 | public function testAfter($array_male, $array_female) 59 | { 60 | $array_male = Pix_Array::factory($array_male); 61 | $array_female = Pix_Array::factory($array_female); 62 | $array_merged = new Pix_Array_Merger($array_male, $array_female); 63 | 64 | // age > 26 65 | $actual_result = array(); 66 | foreach ($array_merged->order('age, name DESC')->after(array('age' => 26)) as $person) { 67 | $actual_result[] = $person['name']; 68 | } 69 | $this->assertEquals($actual_result, array('eva', 'david', 'carole')); // 27, 27, 30 70 | 71 | // age > 27 72 | $actual_result = array(); 73 | foreach ($array_merged->order('age, name DESC')->after(array('age' => 27)) as $person) { 74 | $actual_result[] = $person['name']; 75 | } 76 | $this->assertEquals($actual_result, array('carole')); // 30 77 | 78 | // age >= 27 79 | $actual_result = array(); 80 | foreach ($array_merged->order('age, name DESC')->after(array('age' => 27), true) as $person) { 81 | $actual_result[] = $person['name']; 82 | } 83 | $this->assertEquals($actual_result, array('eva', 'david', 'carole')); // 27, 27, 30 84 | } 85 | 86 | /** 87 | * @dataProvider arrayProvider 88 | */ 89 | public function testKeyAndAfter($array_male, $array_female) 90 | { 91 | $array_male = Pix_Array::factory($array_male); 92 | $array_female = Pix_Array::factory($array_female); 93 | $array_merged = new Pix_Array_Merger($array_male, $array_female); 94 | 95 | $actual_result = array(); 96 | $i = 0; 97 | foreach ($array_merged->order('age, name DESC') as $key => $person) { 98 | $actual_result[] = $person['name']; 99 | $i ++; 100 | if ($i > 1) { 101 | break; 102 | } 103 | } 104 | $this->assertEquals($actual_result, array('fox', 'alice')); // 18, 18 105 | 106 | $actual_result = array(); 107 | $i = 0; 108 | foreach ($array_merged->order('age, name DESC')->after($key) as $key => $person) { 109 | $actual_result[] = $person['name']; 110 | $i ++; 111 | if ($i > 1) { 112 | break; 113 | } 114 | } 115 | $this->assertEquals($actual_result, array('bob', 'eva')); // 24, 27 116 | 117 | $actual_result = array(); 118 | $i = 0; 119 | foreach ($array_merged->order('age, name DESC')->after($key) as $key => $person) { 120 | $actual_result[] = $person['name']; 121 | $i ++; 122 | if ($i > 1) { 123 | break; 124 | } 125 | } 126 | $this->assertEquals($actual_result, array('david', 'carole')); // 27, 30 127 | 128 | $actual_result = array(); 129 | foreach ($array_merged->order('age, name DESC')->after($key) as $key => $person) { 130 | $actual_result[] = $person['name']; 131 | } 132 | $this->assertEquals($actual_result, array()); 133 | } 134 | 135 | /** 136 | * @dataProvider arrayProvider 137 | * @expectedException Pix_Exception 138 | */ 139 | public function testNoOrder($array_male, $array_female) 140 | { 141 | $array_male = Pix_Array::factory($array_male); 142 | $array_female = Pix_Array::factory($array_female); 143 | $array_merged = new Pix_Array_Merger($array_male, $array_female); 144 | 145 | foreach ($array_merged as $row) { 146 | } 147 | } 148 | 149 | public function arrayProvider() 150 | { 151 | return array( 152 | array( 153 | array( 154 | array('name' => 'bob', 'age' => 24, 'height' => 175), 155 | array('name' => 'david', 'age' => 27, 'height' => 183), 156 | array('name' => 'fox', 'age' => 18, 'height' => 165), 157 | ), 158 | array( 159 | array('name' => 'alice', 'age' => 18, 'height' => 158), 160 | array('name' => 'carole', 'age' => 30, 'height' => 163), 161 | array('name' => 'eva', 'age' => 27, 'height' => 171), 162 | ), 163 | ), 164 | ); 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/tests/Pix/Table/SearchTest.php: -------------------------------------------------------------------------------- 1 | assertEquals(get_class($search), 'Pix_Table_Search'); 31 | } 32 | 33 | /** 34 | * @covers Pix_Table_Search::search 35 | */ 36 | public function testSearch() 37 | { 38 | $search = Pix_Table_Search::factory("condiction1"); 39 | 40 | $this->assertEquals($search->getSearchCondictions(), array(array('string', 'condiction1'))); 41 | 42 | $search = $search->search('condiction2'); 43 | $this->assertEquals($search->getSearchCondictions(), array(array('string', 'condiction1'), array('string', 'condiction2'))); 44 | } 45 | 46 | /** 47 | * @covers Pix_Table_Search::getSearchCondictions 48 | */ 49 | public function testGetSearchCondictions() 50 | { 51 | $search = Pix_Table_Search::factory("condiction1"); 52 | 53 | $this->assertEquals($search->getSearchCondictions(), array(array('string', 'condiction1'))); 54 | $this->assertEquals($search->getSearchCondictions('string'), array(array('string', 'condiction1'))); 55 | } 56 | 57 | /** 58 | * @covers Pix_Table_Search::isMapOnly 59 | * @todo Implement testIsMapOnly(). 60 | */ 61 | public function testIsMapOnly() 62 | { 63 | // Remove the following lines when you implement this test. 64 | $this->markTestIncomplete( 65 | 'This test has not been implemented yet.' 66 | ); 67 | } 68 | 69 | /** 70 | * @covers Pix_Table_Search::order 71 | */ 72 | public function testOrder() 73 | { 74 | $search = Pix_Table_Search::factory("condiction1"); 75 | $search = $search->order('id'); 76 | $this->assertEquals($search->order(), array('id' => 'asc')); 77 | 78 | $search = $search->order('id2'); 79 | $this->assertEquals($search->order(), array('id2' => 'asc')); 80 | } 81 | 82 | /** 83 | * @covers Pix_Table_Search::limit 84 | */ 85 | public function testLimit() 86 | { 87 | $search = Pix_Table_Search::factory("condiction1"); 88 | $search = $search->limit(3); 89 | $this->assertEquals($search->limit(), 3); 90 | 91 | $search = $search->limit(null); 92 | $this->assertEquals($search->limit(), null); 93 | } 94 | 95 | /** 96 | * @covers Pix_Table_Search::index 97 | */ 98 | public function testIndex() 99 | { 100 | $search = Pix_Table_Search::factory("condiction1"); 101 | $search = $search->index('index1'); 102 | $this->assertEquals($search->index(), 'index1'); 103 | } 104 | 105 | /** 106 | * @covers Pix_Table_Search::offset 107 | */ 108 | public function testOffset() 109 | { 110 | $search = Pix_Table_Search::factory("condiction1"); 111 | $search = $search->offset(3); 112 | $this->assertEquals($search->offset(), 3); 113 | 114 | $search = $search->offset(null); 115 | $this->assertEquals($search->offset(), null); 116 | } 117 | 118 | /** 119 | * @covers Pix_Table_Search::after 120 | * @todo Implement testAfter(). 121 | */ 122 | public function testAfter() 123 | { 124 | $this->markTestIncomplete( 125 | 'This test has not been implemented yet.' 126 | ); 127 | } 128 | 129 | /** 130 | * @covers Pix_Table_Search::afterInclude 131 | * @todo Implement testAfterInclude(). 132 | */ 133 | public function testAfterInclude() 134 | { 135 | // Remove the following lines when you implement this test. 136 | $this->markTestIncomplete( 137 | 'This test has not been implemented yet.' 138 | ); 139 | } 140 | 141 | /** 142 | * @covers Pix_Table_Search::before 143 | * @todo Implement testBefore(). 144 | */ 145 | public function testBefore() 146 | { 147 | // Remove the following lines when you implement this test. 148 | $this->markTestIncomplete( 149 | 'This test has not been implemented yet.' 150 | ); 151 | } 152 | 153 | /** 154 | * @covers Pix_Table_Search::beforeInclude 155 | * @todo Implement testBeforeInclude(). 156 | */ 157 | public function testBeforeInclude() 158 | { 159 | // Remove the following lines when you implement this test. 160 | $this->markTestIncomplete( 161 | 'This test has not been implemented yet.' 162 | ); 163 | } 164 | 165 | /** 166 | * @covers Pix_Table_Search::reverseOrder 167 | */ 168 | public function testReverseOrder() 169 | { 170 | $this->assertEquals(Pix_Table_Search::reverseOrder(array('id' => 'asc', 'id2' => 'desc')), array('id' => 'desc', 'id2' => 'asc')); 171 | } 172 | 173 | /** 174 | * @covers Pix_Table_Search::getOrderArray 175 | */ 176 | public function testGetOrderArray() 177 | { 178 | $this->assertEquals(Pix_Table_Search::getOrderArray("id"), array('id' => 'asc')); 179 | $this->assertEquals(Pix_Table_Search::getOrderArray("id, id2"), array('id' => 'asc', 'id2' => 'asc')); 180 | $this->assertEquals(Pix_Table_Search::getOrderArray("id,id2"), array('id' => 'asc', 'id2' => 'asc')); 181 | $this->assertEquals(Pix_Table_Search::getOrderArray("id , id2"), array('id' => 'asc', 'id2' => 'asc')); 182 | $this->assertEquals(Pix_Table_Search::getOrderArray("id DESC , id2"), array('id' => 'desc', 'id2' => 'asc')); 183 | $this->assertEquals(Pix_Table_Search::getOrderArray(array('id', 'id2')), array('id' => 'asc', 'id2' => 'asc')); 184 | $this->assertEquals(Pix_Table_Search::getOrderArray(array('id' => 'desc', 'id2' => 'asc')), array('id' => 'desc', 'id2' => 'asc')); 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Table/Search.php: -------------------------------------------------------------------------------- 1 | 0, 'map' => 0, 'term' => 0); 22 | 23 | static public function factory($data = null) 24 | { 25 | if ($data instanceof Pix_Table_Search) { 26 | return $data; 27 | } 28 | 29 | $search = new Pix_Table_Search(); 30 | if (!is_null($data)) { 31 | $search = $search->search($data); 32 | } 33 | return $search; 34 | } 35 | 36 | public function search($search) 37 | { 38 | if (is_scalar($search)) { 39 | if (1 == $search) { 40 | return $this; 41 | } 42 | 43 | // TODO: 看看能不能轉成其他形式, Ex: "a" = 1 ... 44 | $this->_search_conditions[] = array('string', $search); 45 | $this->_search_condition_types['string'] ++; 46 | return $this; 47 | } 48 | 49 | if (is_array($search)) { 50 | foreach ($search as $key => $value) { 51 | $this->_search_conditions[] = array('map', $key, $value); 52 | $this->_search_condition_types['map'] ++; 53 | } 54 | return $this; 55 | } 56 | 57 | if (is_a($search, 'Pix_Table_Search_Term')) { 58 | $this->_search_conditions[] = array('term', $search); 59 | $this->_search_condition_types['term'] ++; 60 | return $this; 61 | } 62 | 63 | throw new Pix_Table_Search_Exception('Unknown search type'); 64 | } 65 | 66 | public function getSearchCondictions($type = null) 67 | { 68 | if (is_null($type)) { 69 | return $this->_search_conditions; 70 | } 71 | 72 | $ret = array(); 73 | foreach ($this->_search_conditions as $condiction) { 74 | if ($condiction[0] != $type) { 75 | continue; 76 | } 77 | $ret[] = $condiction; 78 | } 79 | return $ret; 80 | } 81 | 82 | public function isMapOnly() 83 | { 84 | return $this->_search_condition_types['map'] and (!$this->_search_condition_types['string']) and (!$this->_search_condition_types['term']); 85 | } 86 | 87 | public function order() 88 | { 89 | $args = func_get_args(); 90 | if (!count($args)) { 91 | return $this->_order; 92 | } 93 | $this->_order = self::getOrderArray($args[0]); 94 | return $this; 95 | } 96 | 97 | public function limit() 98 | { 99 | $args = func_get_args(); 100 | if (!count($args)) { 101 | return $this->_limit; 102 | } 103 | $this->_limit = $args[0]; 104 | return $this; 105 | } 106 | 107 | public function index() 108 | { 109 | $args = func_get_args(); 110 | if (!count($args)) { 111 | return $this->_index; 112 | } 113 | $this->_index = $args[0]; 114 | return $this; 115 | } 116 | 117 | public function offset() 118 | { 119 | $args = func_get_args(); 120 | if (!count($args)) { 121 | return $this->_offset; 122 | } 123 | $this->_offset = $args[0]; 124 | return $this; 125 | } 126 | 127 | public function after() 128 | { 129 | $args = func_get_args(); 130 | if (!count($args)) { 131 | return $this->_after; 132 | } 133 | $row = $args[0]; 134 | 135 | $this->_before = null; 136 | $this->_after = is_array($row) ? Pix_Array::factory($row) : $row; 137 | $this->_after_include = array_key_exists(1, $args) ? $args[1] : false; 138 | return $this; 139 | } 140 | 141 | public function afterInclude() 142 | { 143 | return $this->_after_include; 144 | } 145 | 146 | public function before() 147 | { 148 | $args = func_get_args(); 149 | if (!count($args)) { 150 | return $this->_before; 151 | } 152 | $row = $args[0]; 153 | 154 | $this->_after = null; 155 | $this->_before = is_array($row) ? Pix_Array::factory($row) : $row; 156 | $this->_before_include = array_key_exists(1, $args) ? $args[1] : false; 157 | return $this; 158 | } 159 | 160 | public function beforeInclude() 161 | { 162 | return $this->_before_include; 163 | } 164 | 165 | public static function reverseOrder($order) 166 | { 167 | foreach ($order as $column => $way) { 168 | $order[$column] = ('asc' == $order[$column]) ? 'desc' : 'asc'; 169 | } 170 | return $order; 171 | } 172 | 173 | public static function getOrderArray($order) 174 | { 175 | $resultorder = array(); 176 | if (is_array($order)) { 177 | foreach ($order as $column => $way) { 178 | if (is_int($column)) { 179 | $resultorder[$way] = 'asc'; 180 | continue; 181 | } 182 | 183 | $resultorder[$column] = strtolower($way); 184 | if (!in_array(strtolower($way), array('asc', 'desc'))) { 185 | $resultorder[$column] = 'asc'; 186 | continue; 187 | } 188 | } 189 | } 190 | 191 | if (is_scalar($order)) { 192 | if (in_array($order, array('RAND()', 'RANDOM()'))) { 193 | return $order; 194 | } 195 | $orders = explode(',', $order); 196 | $resultorder = array(); 197 | foreach ($orders as $ord) { 198 | if (preg_match('#^`?([^` ]*)`?( .*)?$#', trim($ord), $matches)) { 199 | if (array_key_exists(2, $matches) and in_array(strtolower(trim($matches[2])), array('asc', 'desc'))) { 200 | $way = strtolower(trim($matches[2])); 201 | } else { 202 | $way = 'asc'; 203 | } 204 | $resultorder[$matches[1]] = $way; 205 | } else { 206 | throw new Pix_Array_Exception('->order($order) 的格式無法判斷'); 207 | } 208 | } 209 | } 210 | return $resultorder; 211 | } 212 | } 213 | -------------------------------------------------------------------------------- /webdata/models/Unit.php: -------------------------------------------------------------------------------- 1 | id] = $columngroup->name; 13 | } 14 | } 15 | 16 | $data = new StdClass; 17 | foreach (UnitData::search(array('id' => $this->id)) as $unitdata) { 18 | $data->{self::$_columns[$unitdata->column_id]} = json_decode($unitdata->value); 19 | } 20 | return $data; 21 | } 22 | 23 | public function updateSearch() 24 | { 25 | $curl = curl_init(); 26 | $url = getenv('SEARCH_URL') . '/company/company/' . $this->id(); 27 | curl_setopt($curl, CURLOPT_URL, $url); 28 | curl_setopt($curl, CURLOPT_HEADER, 0); 29 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 30 | curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); 31 | curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($this->getData())); 32 | $ret = curl_exec($curl); 33 | } 34 | 35 | public function id() 36 | { 37 | return str_pad($this->id, 8, '0', STR_PAD_LEFT); 38 | } 39 | 40 | public function name($depth = 0) 41 | { 42 | $prefix = ''; 43 | if (1 == $this->type) { // 公司 44 | $column_id = 2; 45 | } elseif (2 == $this->type) { // 商業登記 46 | $column_id = 33; 47 | } elseif (3 == $this->type) { // 分公司 48 | // 先取總公司 49 | $data = UnitData::search(array('id' => $this->id, 'column_id' => 50))->first(); 50 | if (!$data) { 51 | return ''; 52 | } 53 | $unit = Unit::find(json_decode($data->value)); 54 | if (!$unit) { 55 | return ''; 56 | } 57 | if ($depth) { 58 | return false; 59 | } 60 | $prefix = $unit->name($depth + 1); 61 | if (false === $prefix) { 62 | return ''; 63 | } 64 | $column_id = 48; 65 | } else { 66 | $column_id = 43; 67 | } 68 | 69 | if ($data = UnitData::search(array('id' => $this->id, 'column_id' => $column_id))->first()) { // 公司名稱 70 | $v = json_decode($data->value); 71 | if (is_scalar($v)) { 72 | return $prefix . $v; 73 | } elseif (is_array($v)) { 74 | return $prefix . $v[0]; 75 | } 76 | } 77 | } 78 | 79 | public function get($column) 80 | { 81 | return UnitData::search(array('id' => $this->id, 'column_id' => ColumnGroup::getColumnId($column)))->first(); 82 | } 83 | 84 | public function updateData($data) 85 | { 86 | $data = (array)$data; 87 | $old_data = array(); 88 | foreach (UnitData::search(array('id' => $this->id)) as $unitdata) { 89 | $old_data[$unitdata->column_id] = $unitdata->value; 90 | } 91 | 92 | $add_data = $delete_data = $modify_data = array(); 93 | foreach ($data as $column => $value) { 94 | $column_id = ColumnGroup::getColumnId($column); 95 | 96 | if (!array_key_exists($column_id, $old_data)) { 97 | $add_data[] = $column_id; 98 | } elseif (json_encode($value, JSON_UNESCAPED_UNICODE) != $old_data[$column_id]) { 99 | $modify_data[] = $column_id; 100 | } 101 | } 102 | 103 | foreach ($old_data as $column_id => $value) { 104 | if (!array_key_exists(ColumnGroup::getColumnName($column_id), $data)) { 105 | $delete_data[] = $column_id; 106 | } 107 | } 108 | 109 | if (count($add_data) + count($modify_data) + count($delete_data) == 0) { 110 | return; 111 | } 112 | $now = time(); 113 | 114 | foreach ($add_data as $column_id) { 115 | $value = json_encode($data[ColumnGroup::getColumnName($column_id)], JSON_UNESCAPED_UNICODE); 116 | UnitData::insert(array( 117 | 'id' => $this->id, 118 | 'column_id' => $column_id, 119 | 'value' => $value, 120 | )); 121 | UnitChangeLog::insert(array( 122 | 'id' => $this->id, 123 | 'updated_at' => $now, 124 | 'column_id' => $column_id, 125 | 'old_value' => '', 126 | 'new_value' => $value, 127 | )); 128 | } 129 | 130 | foreach ($modify_data as $column_id) { 131 | $value = json_encode($data[ColumnGroup::getColumnName($column_id)], JSON_UNESCAPED_UNICODE); 132 | $unitdata = UnitData::find(array($this->id, $column_id)); 133 | $unitdata->update(array( 134 | 'value' => json_encode($data[ColumnGroup::getColumnName($column_id)], JSON_UNESCAPED_UNICODE), 135 | )); 136 | try { 137 | UnitChangeLog::insert(array( 138 | 'id' => $this->id, 139 | 'updated_at' => $now, 140 | 'column_id' => $column_id, 141 | 'old_value' => $old_data[$column_id], 142 | 'new_value' => $value, 143 | )); 144 | } catch (Pix_Table_DuplicateException $e) { 145 | } 146 | } 147 | 148 | foreach ($delete_data as $column_id) { 149 | try { 150 | UnitChangeLog::insert(array( 151 | 'id' => $this->id, 152 | 'updated_at' => $now, 153 | 'column_id' => $column_id, 154 | 'old_value' => $old_data[$column_id], 155 | 'new_value' => '', 156 | )); 157 | } catch (Pix_Table_DuplicateException $e) { 158 | } 159 | UnitData::find(array($this->id, $column_id))->delete(); 160 | } 161 | $this->update(array('updated_at' => $now)); 162 | } 163 | } 164 | 165 | class Unit extends Pix_Table 166 | { 167 | public function init() 168 | { 169 | $this->_name = 'unit'; 170 | $this->_primary = 'id'; 171 | $this->_rowClass = 'UnitRow'; 172 | 173 | $this->_columns['id'] = array('type' => 'int', 'unsigned' => true); 174 | // 1 - 公司, 2 - 商業登記, 3 - 工廠登記, 4 - 教育部, 99 - 未知來源 175 | $this->_columns['type'] = array('type' => 'tinyint'); 176 | $this->_columns['updated_at'] = array('type' => 'int'); 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Array/Array.php: -------------------------------------------------------------------------------- 1 | _data = $data; 33 | $this->_cur_data = $data; 34 | } 35 | 36 | public function getRand($count = null) 37 | { 38 | $rand_data = $this->_data; 39 | shuffle($rand_data); 40 | if ($count) { 41 | return new Pix_Array_Array(array_slice($rand_data, 0, $count)); 42 | } else { 43 | return $rand_data[0]; 44 | } 45 | } 46 | 47 | public function getOffset() 48 | { 49 | return $this->_offset; 50 | } 51 | 52 | public function offset($offset = 0) 53 | { 54 | $this->_offset = $offset; 55 | return $this; 56 | } 57 | 58 | public function _sort($a, $b) 59 | { 60 | $way_num = array('asc' => 1, 'desc' => -1); 61 | foreach ($this->_order as $column => $way) { 62 | if (is_array($a)) { 63 | if (!array_key_exists($column, $a) or !array_key_exists($column, $b)) { 64 | return 0; 65 | } 66 | if (strtolower($a[$column]) > strtolower($b[$column])) { 67 | return $way_num[$way]; 68 | } 69 | if (strtolower($a[$column]) < strtolower($b[$column])) { 70 | return -1 * $way_num[$way]; 71 | } 72 | } else { 73 | if (strtolower($a->{$column}) > strtolower($b->{$column})) { 74 | return $way_num[$way]; 75 | } 76 | if (strtolower($a->{$column}) < strtolower($b->{$column})) { 77 | return -1 * $way_num[$way]; 78 | } 79 | } 80 | } 81 | return 0; 82 | } 83 | 84 | public function getOrder() 85 | { 86 | return $this->_order; 87 | } 88 | 89 | public function order($order = null) 90 | { 91 | $obj = clone $this; 92 | $obj->_order = Pix_Table_Search::getOrderArray($order); 93 | return $obj; 94 | } 95 | 96 | public function getLimit() 97 | { 98 | return $this->_limit; 99 | } 100 | 101 | public function limit($limit = null) 102 | { 103 | $obj = clone $this; 104 | $obj->_limit = $limit; 105 | return $obj; 106 | } 107 | 108 | public function sum($column = null) 109 | { 110 | if (!$column) { 111 | return array_sum($this->_data); 112 | } 113 | throw new Pix_Array_Exception('TODO'); 114 | } 115 | 116 | public function max($column = null) 117 | { 118 | throw new Pix_Array_Exception('TODO'); 119 | } 120 | 121 | public function min($column = null) 122 | { 123 | throw new Pix_Array_Exception('TODO'); 124 | } 125 | 126 | public function first() 127 | { 128 | return $this->rewind()->current(); 129 | } 130 | 131 | public function toArray($column = null) 132 | { 133 | $ret = array(); 134 | foreach ($this as $key => $row) { 135 | if (is_null($column)) { 136 | $ret[$key] = $row; 137 | } else { 138 | if (is_array($row) and array_key_exists($column, $row)) { 139 | $ret[$key] = $row[$column]; 140 | } elseif (is_object($row)) { 141 | $ret[$key] = $row->{$column}; 142 | } 143 | } 144 | } 145 | return $ret; 146 | } 147 | 148 | public function getPosition($obj) 149 | { 150 | throw new Pix_Array_Exception('TODO'); 151 | } 152 | 153 | public function count() 154 | { 155 | $this->rewind(); 156 | 157 | while ($this->valid()) { 158 | $this->next(); 159 | } 160 | 161 | return $this->_row_count; 162 | } 163 | 164 | public function seek($pos) 165 | { 166 | return $this->_data[$pos]; 167 | } 168 | 169 | public function current() 170 | { 171 | return current($this->_cur_data); 172 | } 173 | 174 | public function next() 175 | { 176 | do { 177 | next($this->_cur_data); 178 | } while ($this->valid() and !$this->filterRow()); 179 | 180 | $this->_row_count ++; 181 | 182 | return $this; 183 | } 184 | 185 | public function key() 186 | { 187 | return key($this->_cur_data); 188 | } 189 | 190 | public function valid() 191 | { 192 | $valid = array_key_exists(key($this->_cur_data), $this->_cur_data); 193 | 194 | if (is_numeric($this->_limit)) { 195 | $valid = ($valid and ($this->_row_count < $this->_limit)); 196 | } 197 | 198 | return $valid; 199 | } 200 | 201 | public function rewind() 202 | { 203 | $this->_cur_data = $this->_data; 204 | if ($this->_order) { 205 | uasort($this->_cur_data, array($this, '_sort')); 206 | } 207 | 208 | $this->_row_count = 0; 209 | 210 | $offset = 0; 211 | while ($this->valid() and $offset < $this->_offset) { 212 | if ($this->filterRow()) { 213 | $offset ++; 214 | } 215 | next($this->_cur_data); 216 | } 217 | 218 | while ($this->valid() and !$this->filterRow()) { 219 | next($this->_cur_data); 220 | } 221 | 222 | return $this; 223 | } 224 | 225 | public function offsetExists($pos) 226 | { 227 | return array_key_exists($pos, $this->_data); 228 | } 229 | 230 | public function offsetGet($pos) 231 | { 232 | return $this->_data[$pos]; 233 | } 234 | 235 | public function __get($name) 236 | { 237 | return $this->_data[$name]; 238 | } 239 | 240 | public function offsetSet($pos, $value) 241 | { 242 | if (is_null($pos)) { 243 | $this->_data[] = $value; 244 | } else { 245 | $this->_data[$pos] = $value; 246 | } 247 | } 248 | 249 | public function offsetUnset($pos) 250 | { 251 | unset($this->_data[$pos]); 252 | } 253 | 254 | public function push($value) 255 | { 256 | return array_push($this->_data, $value); 257 | } 258 | 259 | public function pop() 260 | { 261 | return array_pop($this->_data); 262 | } 263 | 264 | public function shift() 265 | { 266 | return array_shift($this->_data); 267 | } 268 | 269 | public function unshift($value) 270 | { 271 | return array_unshift($this->_data, $value); 272 | } 273 | 274 | public function reverse($preserve_keys = false) 275 | { 276 | return array_reverse($this->_data, $preserve_keys); 277 | } 278 | } 279 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/Pix/Array/Merger.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class Pix_Array_Merger implements Iterator 11 | { 12 | protected $_arrays = array(); 13 | protected $_array_orders = array(); 14 | protected $_array_datas = array(); 15 | protected $_array_last = array(); 16 | protected $_after = null; 17 | protected $_after_included = false; 18 | protected $_chunk_size = 10; 19 | 20 | /** 21 | * __construct 22 | * 23 | * @param $array... arrays you want to merge 24 | * @access public 25 | */ 26 | public function __construct() 27 | { 28 | $this->_arrays = func_get_args(); 29 | } 30 | 31 | /** 32 | * set the order of merged array 33 | * 34 | * @param $order or $orders for each array 35 | * @access public 36 | * @return Pix_Array_Merger 37 | */ 38 | public function order() 39 | { 40 | $orders = func_get_args(); 41 | $rs = clone $this; 42 | 43 | $rs->_array_orders = array(); 44 | foreach ($orders as $order) { 45 | $rs->_array_orders[] = Pix_Table_Search::getOrderArray($order); 46 | } 47 | 48 | return $rs; 49 | } 50 | 51 | public function chunkSize() 52 | { 53 | $args = func_get_args(); 54 | 55 | if (0 == count($args)) { 56 | return $this->_chunk_size; 57 | } 58 | 59 | $rs = clone $this; 60 | $rs->_chunk_size = intval($args[0]); 61 | return $rs; 62 | } 63 | 64 | protected function _fetchArray($pos) 65 | { 66 | if (array_key_exists($pos, $this->_array_last) and $this->_array_last[$pos] === false) { 67 | return ; 68 | } 69 | 70 | $array = $this->_arrays[$pos]->order(array_combine($this->_getSortColumns($pos), $this->_getSortOrders())); 71 | if (array_key_exists($pos, $this->_array_last)) { 72 | $array = $array->after($this->_array_last[$pos]); 73 | } elseif (is_scalar($this->_after)) { 74 | $sort_values = explode('&', $this->_after); 75 | $after_position = array_pop($sort_values); 76 | $sort_values = array_map('urldecode', $sort_values); 77 | $after_data = array_combine($this->_getSortColumns($pos), $sort_values); 78 | 79 | $array = $array->after($after_data, $pos < $after_position); 80 | } elseif (!is_null($this->_after)) { 81 | $array = $array->after($this->_after, $this->_after_included); 82 | } 83 | 84 | foreach ($array->limit($this->_chunk_size) as $row) { 85 | $this->_array_datas[$pos][] = $row; 86 | } 87 | 88 | if (!array_key_exists($pos, $this->_array_datas) or !count($this->_array_datas[$pos])) { 89 | $this->_array_last[$pos] = false; 90 | return false; 91 | } 92 | 93 | return true; 94 | } 95 | 96 | protected function _getSortOrders() 97 | { 98 | return array_values($this->_array_orders[0]); 99 | } 100 | 101 | protected function _getSortColumns($pos) 102 | { 103 | if (array_key_exists($pos, $this->_array_orders)) { 104 | return array_keys($this->_array_orders[$pos]); 105 | } 106 | 107 | if (array_key_exists(0, $this->_array_orders)) { 108 | return array_keys($this->_array_orders[0]); 109 | } 110 | 111 | throw new Pix_Exception('unknown order'); 112 | } 113 | 114 | public function after($position, $included = false) 115 | { 116 | $rs = clone $this; 117 | $rs->_after = $position; 118 | $rs->_after_included = $included; 119 | return $rs; 120 | } 121 | 122 | public function rewind() 123 | { 124 | $this->_array_datas = array(); 125 | $this->_array_last = array(); 126 | $this->next(); 127 | } 128 | 129 | protected $_current = null; 130 | protected $_current_pos = null; 131 | 132 | public function next() 133 | { 134 | $this->_current = null; 135 | $min_pos = null; 136 | $min_row = null; 137 | 138 | foreach ($this->_arrays as $pos => $array) { 139 | // fetch more rows from array if it is empty 140 | if (!array_key_exists($pos, $this->_array_datas) or !count($this->_array_datas[$pos])) { 141 | if (!$this->_fetchArray($pos)) { 142 | continue; 143 | } 144 | } 145 | $data = $this->_array_datas[$pos]; 146 | 147 | if (is_null($min_pos)) { 148 | $min_pos = $pos; 149 | $min_row = $data[0]; 150 | $min_columns = $this->_getSortColumns($pos); 151 | continue; 152 | } 153 | 154 | // compare current_row to min_row 155 | $current_row = $data[0]; 156 | 157 | $sort_orders = $this->_getSortOrders(); 158 | 159 | foreach ($this->_getSortColumns($pos) as $i => $column) { 160 | if (is_array($current_row)) { 161 | $current_value = $current_row[$column]; 162 | } else { 163 | $current_value = $current_row->{$column}; 164 | } 165 | 166 | if (is_array($min_row)) { 167 | $min_value = $min_row[$min_columns[$i]]; 168 | } else { 169 | $min_value = $min_row->{$min_columns[$i]}; 170 | } 171 | if ('asc' == $sort_orders[$i]) { 172 | if ($current_value < $min_value) { 173 | break; 174 | } elseif ($current_value > $min_value) { 175 | continue 2; 176 | } 177 | } else { 178 | if ($current_value > $min_value) { 179 | break; 180 | } elseif ($current_value < $min_value) { 181 | continue 2; 182 | } 183 | } 184 | } 185 | 186 | $min_pos = $pos; 187 | $min_row = $current_row; 188 | $min_columns = $this->_getSortColumns($pos); 189 | } 190 | 191 | if (is_null($min_pos)) { 192 | return null; 193 | } 194 | 195 | $this->_current = array_shift($this->_array_datas[$min_pos]); 196 | $this->_current_pos = $min_pos; 197 | $this->_array_last[$min_pos] = $this->_current; 198 | } 199 | 200 | public function current() 201 | { 202 | return $this->_current; 203 | } 204 | 205 | public function key() 206 | { 207 | $sort_values = array(); 208 | foreach ($this->_getSortColumns($this->_current_pos) as $column) { 209 | $current = $this->_current; 210 | if (is_array($current)) { 211 | $sort_values[] = urlencode($current[$column]); 212 | } else { 213 | $sort_values[] = urlencode($current->$column); 214 | } 215 | } 216 | $sort_values[] = $this->_current_pos; 217 | return implode('&', $sort_values); 218 | } 219 | 220 | public function valid() 221 | { 222 | return !is_null($this->_current); 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /webdata/stdlibs/pixframework/coverage/Cache.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Pix Framework 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 38 | 39 | 40 | 41 | 42 |
Pix Framework
17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 35 | 36 |
Current directory:/big/home/users/srwang/work/pixframework/Pix/Cache
Legend: 25 | 26 | Low: 0% to 35% 27 | 28 | 29 | Medium: 35% to 70% 30 | 31 | 32 | High: 70% to 100% 33 | 34 |
37 |
43 | 44 |
45 | 46 |
47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 67 | 68 | 69 | 76 | 77 | 78 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 101 | 102 | 103 | 110 | 111 | 112 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 132 | 133 | 134 | 141 | 142 | 143 | 150 | 151 | 152 | 153 | 154 | 155 |
 Coverage
 LinesFunctions / MethodsClasses
Total 61 | 62 | 63 | 64 | 65 |
0.00%0.00%
66 |
0.00%0 / 255 70 | 71 | 72 | 73 | 74 |
0.00%0.00%
75 |
0.00%0 / 63 79 | 80 | 81 | 82 | 83 |
0.00%0.00%
84 |
0.00%0 / 6
 
Adapter 95 | 96 | 97 | 98 | 99 |
0.00%0.00%
100 |
0.00%0 / 239 104 | 105 | 106 | 107 | 108 |
0.00%0.00%
109 |
0.00%0 / 58 113 | 114 | 115 | 116 | 117 |
0.00%0.00%
118 |
0.00%0 / 5
Adapter.php 126 | 127 | 128 | 129 | 130 |
0.00%0.00%
131 |
0.00%0 / 16 135 | 136 | 137 | 138 | 139 |
0.00%0.00%
140 |
0.00%0 / 5 144 | 145 | 146 | 147 | 148 |
0.00%0.00%
149 |
0.00%0 / 1
156 |
157 | 158 |
159 | 160 | 161 | 162 | 163 |
Generated by PHPUnit 3.4.15 and Xdebug 2.1.3 using PHP 5.3.10 at Tue Apr 24 16:09:33 CST 2012.
164 | 165 |
166 | 167 | 168 | --------------------------------------------------------------------------------