Code: Select all
<?php
class Article(){
static protected $_statuses = array('', 'deleted', 'archived', 'updatedByEditor', 'updatedByAuthor', 'published', 'hidden');
public __construct($attrs = array(), $save = FALSE){
foreach ($attrs as $name => $value) {
$this->attrs[$name] = $value;
}
if ($save) {
$this->save();
}
}
function save(){
if (isset($this->id)) {
$this->update();
} else {
$this->create();
}
}
function update(){
$attrs = array();
foreach ($this as $name => $var) {
if ($name{0} != '_') { //underscore denotes "system" attributes
$attrs[$name] = $var;
}
}
unset($attrs['id']);
self::checkId($this->id);
if (isset($attrs['category'])) {
self::checkCategory($attrs['category']);
}
if (isset($attrs['status'])) {
self::checkStatus($attrs['status']);
}
if (isset($attrs['title'])) {
self::checkTitle($attrs['title']);
}
if (isset($attrs['preface'])) {
self::checkPreface($attrs['preface']);
}
if (isset($attrs['text'])) {
self::checkText($attrs['text']);
}
if (isset($attrs['time'])) {
$attrs['time'] = time2iso($attrs['time']);
}
if (isset($attrs['info'])) {
$attrs['info'] = Ori::fold($attrs['info']);
}
$set = QMaster::makeUpdate($attrs);
$query = "UPDATE articles SET $set
WHERE `id` = '$id'";
$result = mysql_query($query);
if (!$result) {
throw new Exception("Invalid query: [<i>$query</i>] ".mysql_error());
}
if (mysql_affected_rows() < 0) {
return FALSE;
}
return TRUE;
}
function create(){
$attrs = array();
foreach ($this as $name => $var) {
if ($name{0} != '_') {
$attrs[$name] = $var;
}
}
self::checkCategory($attrs['category']);
self::checkStatus($attrs['status']);
self::checkTitle($attrs['title']);
self::checkPreface($attrs['preface']);
self::checkText($attrs['text']);
$attrs['time'] = time2iso($attrs['time']);
$attrs['info'] = Ori::fold($attrs['info']);
list($names, $values) = QMaster::makeInsert($attrs);
$query = "INSERT INTO `articles` ($names) VALUES ($values)";
$result = mysql_query($query);
if (!$result) {
throw new Exception("Invalid query: [<i>$query</i>] ".mysql_error());
}
if ($this->attrs['id'] == 0) {
return FALSE;
}
$this->id = mysql_insert_id();
return $this->id;
}
static function checkId($value){
if ((int) $value < 1) {
throw new UserException('Invalid id');
}
}
static function checkCategory($value){
if ((int) $value < 0) {
throw new UserException('Invalid category');
}
}
static function checkStatus($value){
if (!in_array($value, self::$_statuses)) {
throw new UserException('Invalid status');
}
}
static function checkTitle($value){
if (strlen($value) > 100 || empty($value)
|| strpos($value, "\n") !== FALSE) {
throw new UserException('Invalid title');
}
}
static function checkPreface($value){
if (strlen($value) > 3000) {
throw new UserException('Invalid preface');
}
}
static function checkText($value){
if (strlen($value) > 200000) {
throw new UserException('Invalid text');
}
}
static function get($id){
self::checkId($id);
$query = "SELECT * FROM `articles` WHERE `id` = '$id'";
$result = mysql_query($query);
if (!$result) {
throw new Exception("Invalid query: [<i>$query</i>] ".mysql_error());
}
$article = mysql_fetch_assoc($result);
if (!$article) {
return NULL;
}
$article['time'] = iso2unix();
$article['info'] = Ori::unfold($article['info']);
return new Article($article);
}
static function getPage($pageSize, $pageNum = 0, $where = ''){
$pageSize = (int) $pageSize;
if ($pageSize < 1) {
throw new Exception("Invalid page size");
}
$offset = $pageNum * $pageSize;
$query = "SELECT * FROM `articles`";
if (!empty($where)) {
$query .= " WHERE $where";
}
$query .= " LIMIT $pageSize";
if ($offset > 0) {
$query .= " OFFSET $offset";
}
$result = mysql_query($query);
if (!$result) {
throw new Exception("Invalid query: [<i>$query</i>] ".mysql_error());
}
$articles = array();
while ($article = mysql_fetch_assoc($result)) {
$article['time'] = iso2unix();
$article['info'] = Ori::unfold($article['info']);
$articles[] = new Article($article);
}
return $articles;
}
static function delete($id){
self::checkId($id);
$query = "DELETE FROM `articles`
WHERE `id` = '$id'";
$result = mysql_query($query);
if (!$result) {
throw new Exception("Invalid query: [<i>$query</i>] ".mysql_error());
}
if (mysql_affected_rows() < 0) {
return FALSE;
} else {
return TRUE;
}
}
}
?>Some people do it like this:
$o = new Article();
$article->setX($x);
$article->setY($y);
$article->create();
Lots of redundant typing and methods calls.
Other way:
$id = Article::create(array('x'=>$x, 'y'=>$y));
IMO better, but later I will need to update the same article in some way.
So I do something like this, right?
$article = Article::get($id); //query
$article->bla = 11;
$article->update(); //query
But that's 1 extra query. Not lethal, but it feels wrong.
Another possibility:
$article = new Article(); //no query
$article->bla = 11;
$article->mergeWith($id); //query
The problem is that good object should represent something.
Almost the same thing:
$correction = Article::correctionsFor($id); //no query
$correction->bla = 11;
$correction->perform(); //query
Do I need to create separate ArticleCorrection class? Smells of incorrectly done Java program.
And another one:
$correct = array('bla' => 11);
Article::update($id, $correct);
Looks okay, but that's not object-oriented.
The "right" way:
$article = new Article($id); //no query
$article->bla = 11; //no query, but the class notes that article with creatain $id is updated
//...
$article->__destruct(); //that's where we do cleanup, and save article
//or
$someOtheAttr = $article->someOtheAttr; //article updates db, then reads db to sychronize it's attributes
The only problem with this approach is that class will be bloated, and execution flow would be quite complex. This is how I would do it in Java, but we're speaking about PHP.
Any ideas how to do it "properly"? Am I overanalyzing insignificant problem?