├── .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 | = $this->escape($this->message) ?>
12 | If you are not redirected to = $this->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 | 資料來源是 台灣公司資料 ,不一定會與經濟部商業司資料同步
26 | [Updated 2018-10-12] 自 2018-10 起,資料會自動每月一次從 台灣公司資料 更新,並且在頁面上會顯示最近更新日期,以便得知目前資料版本
27 | 這邊的圖表是以查詢的公司往外最多查詢三層關係,因此有的公司在圖表中沒看到關係,不代表他已經沒有其他關係公司,只是離你正在查詢的公司太遠了,想要確認是否有這狀況,可以再從那個不確定是否有關係的公司再查詢一次
28 | 資料呈現上沒有顯示方向性,因此 A公司 與 B公司 被線連起來,有可能是 A 持有 B ,也有可能是 B 持有 A
29 | 公司的關聯是透過「董事名單」,如果有持股但是沒有被列入董事不會在這邊出現
30 | 如果公司是以個人持股而非代表法人持股,也不會從這邊看的到關聯
31 | 兩家公司出現在這邊不代表是同集團,例如 中華職棒事業股份有限公司 的董事有 統一企業股份有限公司 和 味全食品工業股份有限公司 ,但是統一和味全並不是同一集團。
32 | 程式碼以 BSD License 公開在 https://github.com/ronnywang/company-graph ,歡迎 PULL REQUEST 更好看及更好用的呈現方式
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: = get_class($this->exception) ?>
9 | Exception message: = $this->escape($this->exception->getMessage()) ?>
10 | Stack trace:
11 |
12 |
13 | File
14 | Line
15 | Function
16 | Arguments
17 |
18 | exception->getTrace() as $trace) { ?>
19 |
20 | = $this->escape($trace['file']) ?>
21 | = intval($trace['line']) ?>
22 | = $this->escape($trace['class'] . $trace['type'] . $trace['function']) ?>
23 |
24 |
25 |
26 |
27 |
28 | string: = $this->escape($arg) ?>
29 |
30 | array(= count($arg) ?>)
31 |
32 | = get_class($arg) ?>
33 |
34 | = gettype($arg) ?>
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
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 |
29 | id) { ?>
30 | 計算關係中...
31 |
32 |
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 | Pix Framework
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | Legend:
24 |
25 |
26 | Low: 0% to 35%
27 |
28 |
29 | Medium: 35% to 70%
30 |
31 |
32 | High: 70% to 100%
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | Coverage
51 |
52 |
53 |
54 | Lines
55 | Functions / Methods
56 | Classes
57 |
58 |
59 | Row.php
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | 0.00%
68 | 0 / 3
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | 0.00%
77 | 0 / 1
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | 0.00%
86 | 0 / 1
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
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 | Pix Framework
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | Legend:
24 |
25 |
26 | Low: 0% to 35%
27 |
28 |
29 | Medium: 35% to 70%
30 |
31 |
32 | High: 70% to 100%
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | Coverage
51 |
52 |
53 |
54 | Lines
55 | Functions / Methods
56 | Classes
57 |
58 |
59 | Exception.php
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | 0.00%
68 | 0 / 1
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | 0.00%
86 | 0 / 1
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
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 | Pix Framework
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | Legend:
24 |
25 |
26 | Low: 0% to 35%
27 |
28 |
29 | Medium: 35% to 70%
30 |
31 |
32 | High: 70% to 100%
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | Coverage
51 |
52 |
53 |
54 | Lines
55 | Functions / Methods
56 | Classes
57 |
58 |
59 | Result.php
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | 0.00%
68 | 0 / 8
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | 0.00%
77 | 0 / 4
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | 0.00%
86 | 0 / 1
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
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 | Pix Framework
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | Legend:
24 |
25 |
26 | Low: 0% to 35%
27 |
28 |
29 | Medium: 35% to 70%
30 |
31 |
32 | High: 70% to 100%
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | Coverage
51 |
52 |
53 |
54 | Lines
55 | Functions / Methods
56 | Classes
57 |
58 |
59 | Total
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | 0.00%
68 | 0 / 255
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | 0.00%
77 | 0 / 63
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | 0.00%
86 | 0 / 6
87 |
88 |
89 |
90 |
91 |
92 |
93 | Adapter
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | 0.00%
102 | 0 / 239
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 | 0.00%
111 | 0 / 58
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | 0.00%
120 | 0 / 5
121 |
122 |
123 |
124 | Adapter.php
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 | 0.00%
133 | 0 / 16
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 | 0.00%
142 | 0 / 5
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 | 0.00%
151 | 0 / 1
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
164 |
165 |
166 |
167 |
168 |
--------------------------------------------------------------------------------