public function get($id)
 {
     return queryOne('
 		select
 			*
 		from
 			' . self::$TABELA_PESSOA . '
 		where
 			id=?', array($id));
 }
Ejemplo n.º 2
0
 protected function onValidate()
 {
     if ($this->ac == "set") {
         if (issetval("status")) {
             $status = $_POST["status"];
             if ($status == "RE" || $status == "CA") {
                 $oldStatus = queryOne("SELECT status FROM Ordr WHERE id={$this->id}");
                 if ($oldStatus != "CR") {
                     throw new MyException(E_FORBIDDEN, "forbidden to change status to {$status}");
                 }
                 $this->onAfterActions[] = function () use($status) {
                     $orderId = $this->id;
                     $empId = $_SESSION["empId"];
                     $sql = sprintf("INSERT INTO OrderLog (orderId, action, tm, empId) VALUES ({$orderId},'{$status}','%s', {$empId})", date(FMT_DT));
                     execOne($sql);
                 };
             } else {
                 throw new MyException(E_FORBIDDEN, "forbidden to change status to {$_POST['status']}");
             }
         }
     }
 }
Ejemplo n.º 3
0
/**
@fn tableCRUD($ac, $tbl, $asAdmin?=false)

对象型接口的入口。
也可直接被调用,常与setParam一起使用, 提供一些定制的操作。

@param $asAdmin 默认根据用户身份自动选择"AC_"类; 如果为true, 则以超级管理员身份调用,即使用"AC0_"类。
设置$asAdmin=true好处是对于超级管理员权限来说,即使未定义"AC0_"类,默认也可以访问所有内容。

假如有Rating(订单评价)对象,不想通过对象型接口来查询,而是通过函数型接口来定制输出,接口设计为:

	queryRating(storeId, cond?) -> tbl(id, score, dscr, tm, orderDscr)

	查询店铺storeId的订单评价。

	应用逻辑:
	- 按时间tm倒排序

底层利用tableCRUD实现它,这样便于保留分页、参数cond/gres等特性:

	function api_queryRating()
	{
		$storeId = mparam("storeId");

		// 定死输出内容。
		setParam("res", "id, score, dscr, tm, orderDscr");

		// 相当于AccessControl框架中调用 addCond,用Obj.query接口的内部参数cond2以保证用户还可以使用cond参数。
		setParam("cond2", ["o.storeId=$storeId"]); 

		// 定死排序条件
		setParam("orderby", "tm DESC");

		$ret = tableCRUD("query", "Rating", true);
		return $ret;
	}

注意:
- 以上示例中的设计不可取,应使用标准对象接口来实现这个需求。

@see setParam
*/
function tableCRUD($ac1, $tbl, $asAdmin = false)
{
    $accessCtl = AccessControl::create($tbl, $asAdmin);
    $accessCtl->before($ac1);
    $tbl = $accessCtl->getTable();
    $ignoreAfter = false;
    if ($ac1 == "add") {
        $keys = '';
        $values = '';
        #			var_dump($_POST);
        $id = $accessCtl->genId();
        if ($id != 0) {
            $keys = "id";
            $values = (string) $id;
        }
        foreach ($_POST as $k => $v) {
            $k = htmlEscape($k);
            if ($k === "id") {
                continue;
            }
            // ignore non-field param
            if (substr($k, 0, 2) === "p_") {
                continue;
            }
            if ($v === "") {
                continue;
            }
            # TODO: check meta
            if (!preg_match('/^\\w+$/', $k)) {
                throw new MyException(E_PARAM, "bad key {$k}");
            }
            if ($keys !== '') {
                $keys .= ", ";
                $values .= ", ";
            }
            $keys .= $k;
            $values .= Q(htmlEscape($v));
        }
        if (strlen($keys) == 0) {
            throw new MyException(E_PARAM, "no field found to be added");
        }
        $sql = sprintf("INSERT INTO %s (%s) VALUES (%s)", $tbl, $keys, $values);
        #			var_dump($sql);
        $id = execOne($sql, true);
        $res = param("res");
        if (isset($res)) {
            setParam("id", $id);
            $ret = tableCRUD("get", $tbl);
        } else {
            $ret = $id;
        }
    } elseif ($ac1 == "set") {
        $id = mparam("id", $_GET);
        $kv = "";
        foreach ($_POST as $k => $v) {
            $k = htmlEscape($k);
            if ($k === 'id') {
                continue;
            }
            // ignore non-field param
            if (substr($k, 0, 2) === "p_") {
                continue;
            }
            # TODO: check meta
            if (!preg_match('/^\\w+$/', $k)) {
                throw new MyException(E_PARAM, "bad key {$k}");
            }
            if ($kv !== '') {
                $kv .= ", ";
            }
            // 空串或null置空;empty设置空字符串
            if ($v === "" || $v === "null") {
                $kv .= "{$k}=null";
            } else {
                if ($v === "empty") {
                    $kv .= "{$k}=''";
                } else {
                    if (startsWith($k, "flag_") || startsWith($k, "prop_")) {
                        $kv .= flag_getExpForSet($k, $v);
                    } else {
                        $kv .= "{$k}=" . Q(htmlEscape($v));
                    }
                }
            }
        }
        if (strlen($kv) == 0) {
            addLog("no field found to be set");
        } else {
            $sql = sprintf("UPDATE %s SET %s WHERE id=%d", $tbl, $kv, $id);
            $cnt = execOne($sql);
        }
        $ret = "OK";
    } elseif ($ac1 === "get" || $ac1 === "query") {
        $forGet = $ac1 === "get";
        $wantArray = param("wantArray/b");
        $sqlConf = $accessCtl->sqlConf;
        $enablePaging = true;
        if ($forGet || $wantArray) {
            $enablePaging = false;
        }
        if ($forGet) {
            $id = mparam("id");
            array_unshift($sqlConf["cond"], "t0.id={$id}");
        } else {
            $pagesz = param("_pagesz/i");
            $pagekey = param("_pagekey/i");
            // support jquery-easyui
            if (!isset($pagesz) && !isset($pagekey)) {
                $pagesz = param("rows/i");
                $pagekey = param("page/i");
                if (isset($pagekey)) {
                    $enableTotalCnt = true;
                    $enablePartialQuery = false;
                }
            }
            if ($pagesz == 0) {
                $pagesz = 20;
            }
            $maxPageSz = min($accessCtl->getMaxPageSz(), PAGE_SZ_LIMIT);
            if ($pagesz < 0 || $pagesz > $maxPageSz) {
                $pagesz = $maxPageSz;
            }
            if (isset($sqlConf["gres"])) {
                $enablePartialQuery = false;
            }
        }
        $orderSql = $sqlConf["orderby"];
        // setup cond for partialQuery
        if ($enablePaging) {
            if ($orderSql == null) {
                $orderSql = $accessCtl->getDefaultSort();
            }
            if (!isset($enableTotalCnt)) {
                $enableTotalCnt = false;
                if ($pagekey === 0) {
                    $enableTotalCnt = true;
                }
            }
            // 如果未指定orderby或只用了id(以后可放宽到唯一性字段), 则可以用partialQuery机制(性能更好更精准), _pagekey表示该字段的最后值;否则_pagekey表示下一页页码。
            if (!isset($enablePartialQuery)) {
                $enablePartialQuery = false;
                if (preg_match('/^(t0\\.)?id\\b/', $orderSql)) {
                    $enablePartialQuery = true;
                    if ($pagekey) {
                        if (preg_match('/\\bid DESC/i', $orderSql)) {
                            $partialQueryCond = "t0.id<{$pagekey}";
                        } else {
                            $partialQueryCond = "t0.id>{$pagekey}";
                        }
                        // setup res for partialQuery
                        if ($partialQueryCond) {
                            // 							if (isset($sqlConf["res"][0]) && !preg_match('/\bid\b/',$sqlConf["res"][0])) {
                            // 								array_unshift($sqlConf["res"], "t0.id");
                            // 							}
                            array_unshift($sqlConf["cond"], $partialQueryCond);
                        }
                    }
                }
            }
            if (!$pagekey) {
                $pagekey = 1;
            }
        }
        if (!isset($sqlConf["res"][0])) {
            $sqlConf["res"][0] = "t0.*";
        } else {
            if ($sqlConf["res"][0] === "") {
                array_shift($sqlConf["res"]);
            }
        }
        $resSql = join(",", $sqlConf["res"]);
        if ($resSql == "") {
            $resSql = "t0.id";
        }
        if (@$sqlConf["distinct"]) {
            $resSql = "DISTINCT {$resSql}";
        }
        $tblSql = "{$tbl} t0";
        if (count($sqlConf["join"]) > 0) {
            $tblSql .= "\n" . join("\n", $sqlConf["join"]);
        }
        $condSql = "";
        foreach ($sqlConf["cond"] as $cond) {
            if ($cond == null) {
                continue;
            }
            if (strlen($condSql) > 0) {
                $condSql .= " AND ";
            }
            if (stripos($cond, " and ") !== false || stripos($cond, " or ") !== false) {
                $condSql .= "({$cond})";
            } else {
                $condSql .= $cond;
            }
        }
        /*
        			foreach ($_POST as $k=>$v) {
        				# skip sys param which generally starts with "_"
        				if (substr($k, 0, 1) === "_")
        					continue;
        				# TODO: check meta
        				if (! preg_match('/^\w+$/', $k))
        					throw new MyException(E_PARAM, "bad key $k");
        
        				if ($condSql !== '') {
        					$condSql .= " AND ";
        				}
        				$condSql .= KVtoCond($k, $v);
        			}
        */
        $sql = "SELECT {$resSql} FROM {$tblSql}";
        if ($condSql) {
            flag_handleCond($condSql);
            $sql .= "\nWHERE {$condSql}";
        }
        if (isset($sqlConf["union"])) {
            $sql .= "\nUNION\n" . $sqlConf["union"];
        }
        if ($sqlConf["gres"]) {
            $sql .= "\nGROUP BY {$sqlConf['gres']}";
        }
        if ($orderSql) {
            $sql .= "\nORDER BY " . $orderSql;
        }
        if ($enablePaging) {
            if ($enableTotalCnt) {
                $cntSql = "SELECT COUNT(*) FROM {$tblSql}";
                if ($condSql) {
                    $cntSql .= "\nWHERE {$condSql}";
                }
                $totalCnt = queryOne($cntSql);
            }
            if ($enablePartialQuery) {
                $sql .= "\nLIMIT " . $pagesz;
            } else {
                $sql .= "\nLIMIT " . ($pagekey - 1) * $pagesz . "," . $pagesz;
            }
        } else {
            if ($pagesz) {
                $sql .= "\nLIMIT " . $pagesz;
            }
        }
        if ($forGet) {
            $ret = queryOne($sql, PDO::FETCH_ASSOC);
            if ($ret === false) {
                throw new MyException(E_PARAM, "not found `{$tbl}.id`=`{$id}`");
            }
            handleSubObj($sqlConf["subobj"], $id, $ret);
        } else {
            $ret = queryAll($sql, PDO::FETCH_ASSOC);
            if ($ret === false) {
                $ret = [];
            }
            if ($wantArray) {
                foreach ($ret as &$mainObj) {
                    $id1 = $mainObj["id"];
                    handleSubObj($sqlConf["subobj"], $id1, $mainObj);
                }
            } else {
                // Note: colCnt may be changed in after().
                $fixedColCnt = count($ret) == 0 ? 0 : count($ret[0]);
                $accessCtl->after($ret);
                $ignoreAfter = true;
                if ($enablePaging && $pagesz == count($ret)) {
                    // 还有下一页数据, 添加nextkey
                    if ($enablePartialQuery) {
                        $nextkey = $ret[count($ret) - 1]["id"];
                    } else {
                        $nextkey = $pagekey + 1;
                    }
                }
                $ret = objarr2table($ret, $fixedColCnt);
                if (isset($nextkey)) {
                    $ret["nextkey"] = $nextkey;
                }
                if (isset($totalCnt)) {
                    $ret["total"] = $totalCnt;
                }
                handleFormat($ret, $tbl);
            }
        }
    } elseif ($ac1 == "del") {
        $id = mparam("id");
        $sql = sprintf("DELETE FROM %s WHERE id=%d", $tbl, $id);
        $cnt = execOne($sql);
        if ($cnt != 1) {
            throw new MyException(E_PARAM, "not found id={$id}");
        }
        $ret = "OK";
    }
    if (!$ignoreAfter) {
        $accessCtl->after($ret);
    }
    return $ret;
}
Ejemplo n.º 4
0
function api_att()
{
    // overwritten the default
    header("Cache-Control: private, max-age=99999999");
    //header("Cache-Control: private");
    header("Pragma: ");
    // session_start() set this one to "no-cache"
    #checkAuth(AUTH_USER | AUTH_EMP);
    #$uid = $_SESSION["uid"];
    $id = param("id");
    $thumbId = param("thumbId");
    if ((is_null($id) || $id <= 0) && (is_null($thumbId) || $thumbId <= 0)) {
        header(HTTP_NOT_FOUND);
        exit;
    }
    // setup cache via etag.
    $etag = null;
    if (is_null($thumbId)) {
        $etag = "att-{$id}";
    } else {
        $etag = "att-t{$thumbId}";
    }
    @($etag1 = $_SERVER['HTTP_IF_NONE_MATCH']);
    if ($etag1 == $etag) {
        header("Etag: {$etag}", true, 304);
        exit;
    }
    if ($id !== null) {
        $sql = "SELECT path FROM Attachment WHERE id={$id}";
    } else {
        # a1: original, a2: thumb
        $sql = "SELECT a1.path FROM Attachment a1 INNER JOIN Attachment a2 ON a1.id=a2.orgPicId WHERE a2.id={$thumbId}";
    }
    $file = queryOne($sql);
    if ($file === false) {
        header(HTTP_NOT_FOUND);
        exit;
    }
    if (preg_match('/http:/', $file)) {
        header('Location: ' . $file);
        throw new DirectReturn();
    }
    chdir($GLOBALS["BASE_DIR"]);
    if (!is_file($file)) {
        header(HTTP_NOT_FOUND);
        exit;
    }
    # 对指定mime的直接返回,否则使用重定向。
    # TODO: 使用 apache x-sendfile module 解决性能和安全性问题。
    $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
    global $ALLOWED_MIME;
    //$mimeType = $ALLOWED_MIME[$ext] ?: 'application/octet-stream';
    $mimeType = $ALLOWED_MIME[$ext];
    if (@$mimeType) {
        header("Content-Type: {$mimeType}");
        header("Etag: {$etag}");
        #header("Expires: Thu, 3 Sep 2020 08:52:00 GMT");
        #header("Content-length: " . filesize($file));
        #header('Content-Disposition: attachment; filename='.basename($file));
        readfile($file);
    } else {
        $baseUrl = getBaseUrl(false);
        $url = $baseUrl . $file;
        header('Location: ' . $url);
    }
    throw new DirectReturn();
}