hashbang/joyst

基于数据库模式的 CodeIgniter 扩展,提供自动模型功能

v0.3.2 2014-10-11 05:20 UTC

This package is not auto-updated.

Last update: 2024-09-24 01:30:56 UTC


README

Joyst 是一个 CodeIgniter 扩展,提供基于数据库模式的自动模型功能。

Joyst 的目标如下

  1. 自动化 CodeIgniter 中模型繁琐的指定 - 它通过自动提供常见功能如 get()getAll()getById() 等。
  2. 自动化简单任务(如 CRUD)从前端到后端的数据层访问。

安装

通过 Composer 安装

composer require hashbang/joyst

常见错误

  • 致命错误:未找到类 'Joyst_Controller' - Joyst 需要在 CI 加载顺序的非常早期加载。请将 require('vendor/autoload.php'); 的调用添加到 application/config/config.php,而不是自动加载文件。

在 CodeIgniter 中使用

简单示例

以下是一个使用 Joyst 的 CodeIgniter 模型示例,它提供了用户模型功能。以下示例中唯一重要的是类扩展了 Joyst_Model 并有一个名为 DefineSchema() 的函数(任何大小写)。

class User extends Joyst_Model {

	function DefineSchema() {
		$this->On('getall', function(&$where) {
			if (!isset($where['status'])) // If not specified imply only active users
				$where['status'] = 'active';
		});
		$this->On('create', function(&$row) {
			$row['created'] = time(); // Set the row creation time when creating
			if (isset($row['email']) && empty($row['username'])) // If no username specified make the username the email
				$row['username'] = $row['email'];
			if (isset($row['password'])) { // If setting a password hash it
				$row['passhash'] = $this->HashSet($row['password']);
				unset($row['password']); // Remove it from the output since we are storing it in another field
			}
		});
		$this->On('save', function($id, &$row) {
			$row['edited'] = time(); // Save the time we edited the record
			if (isset($_SESSION['user']) && $_SESSION['user']['userid'] == $userid) // Changing ourself?
				$_SESSION['user'] = array_merge($_SESSION['user'], $this->Get($userid, TRUE)); // Update $_SESSION['user'] to reflect the new data
		});

		return array( // Specify the table schema
			'_model' => 'User',
			'_table' => 'users',
			'_id' => 'userid',
			'userid' => array(
				'type' => 'pk',
				'readonly' => true,
			),
			'username' => array(
				'type' => 'varchar',
				'length' => 50,
			),
			'fname' => array(
				'type' => 'varchar',
				'length' => 50,
			),
			'lname' => array(
				'type' => 'varchar',
				'length' => 50,
			),
			'passhash' => array(
				'type' => 'char',
				'length' => 40,
			),
			'email' => array(
				'type' => 'email',
			),
			'role' => array(
				'type' => 'enum',
				'options' => array(
					'user' => 'Regular user',
					'admin' => 'Administrator',
					'root' => 'Root user'
				),
				'default' => 'user',
			),
			'created' => array(
				'type' => 'epoc',
				'readonly' => true,
			),
			'edited' => array(
				'type' => 'epoc',
				'readonly' => true,
			),
			'lastlogin' => array(
				'type' => 'epoc',
				'readonly' => true,
			),
			'status' => array(
				'type' => 'enum',
				'options' => array('active', 'deleted'),
				'default' => 'active',
			),
		);
	}
}

复杂示例

以下示例模型提供了通用设备功能。

class Device extends Joyst_Model {

	function DefineSchema() {
		$this->On('getall', function(&$where) {
			if (!isset($where['status'])) // If not specified imply only active items
				$where['status'] = 'active';
		});
		$this->On('create', function(&$row) {
			$row['created'] = time();
			$row['creatorid'] = $_SESSION['user']['userid']; // Set the creator to the current user
		});
		$this->On('save', function($id, &$row) {
			$row['edited'] = time();
			if (isset($row['starred'])) // If we're being passed the meta field 'starred' call our defined function SetStar()
				$this->SetStar($id, $row['starred']);
		});
		$this->on('row', function(&$row) {
			$row['starred'] = $this->IsStarred($row['deviceid']); // Append the meta field 'starred' to the output of each row

			$row['isActive'] = $this->IsActive($row); // Append the meta field 'isActive' to the output of each row
		});
		$this->on('getall', function(&$where) {
			$this->db->select('devices.*');

			// Example of a meta field 'tagid' inserting an automatic join to filter by
			if (isset($where['tagid'])) {
				$this->db->join('tags2devices', 'tags2devices.deviceid = devices.deviceid');
				$this->db->where('tags2devices.tagid', $where['tagid']);
				unset($where['tagid']);
			}

			// Example of another join if the meta field 'starred' is specified in the where condition
			if (isset($where['starred'])) {
				$this->db->join('user2device', 'user2device.deviceid = devices.deviceid');
				$this->db->where('user2device.userid', $this->User->GetActive('userid'));
				unset($where['starred']);
			}

			$this->db->join('dcus', 'dcus.dcuid = devices.dcuid');
			$this->db->where('dcus.locationid', $this->User->GetActive('locationid'));
		});
		$this->on('created', function($deviceid, $row) {
			// Log that we created the item
			$this->Log->Add('device', "Device #$deviceid created", null, array('deviceid' => $deviceid));
		});

		return array(
			'_model' => 'Device',
			'_table' => 'devices',
			'_id' => 'deviceid',
			'deviceid' => array(
				'type' => 'pk',
				'readonly' => true,
			),
			'dcuid' => array(
				'type' => 'fk',
			),
			'ref' => array(
				'type' => 'varchar',
				'length' => 50,
			),
			'name' => array(
				'type' => 'varchar',
				'length' => 100,
			),
			'description' => array(
				'type' => 'varchar',
				'length' => 255,
			),
			'type' => array(
				'type' => 'enum',
				'options' => array(
					'unknown' => 'Unknown',
					'ac' => 'Air Conditioner',
					'light' => 'Light',
					'hotwater' => 'Hot Water',
					'meter' => 'Meter',
				),
				'default' => 'unknown',
			),
			'spec' => array(
				'type' => 'json',
			),
			'created' => array(
				'type' => 'epoc',
				'readonly' => true,
			),
			'creatorid' => array(
				'type' => 'int',
				'readonly' => true,
			),
			'edited' => array(
				'type' => 'int',
				'readonly' => true,
			),
			'status' => array(
				'type' => 'enum',
				'options' => array('active', 'deleted'),
				'default' => 'active',
			),
		);
	}
}

有用的代码片段

对 GetAll() 的返回值进行排序

有时内置的 OrderBy 功能过于有限,您可能需要在 PHP 高级语言层(PHP HLL)中对返回结果进行重新排列,而不是在数据库中。

以下示例挂钩到 GetAll() 返回值,并应用 自然排序算法,以确保当内容包含数字时(例如,'1'、'2'、'10'、'11' 正确排序)。

$this->on('rows', function(&$rows) {
	return usort($rows, function($a, $b) {
		return strnatcmp($a['name'], $b['name']); // Sort by the name field using a natural string sort
	});
});