CakePHP Icing 插件 - CakePHP 的便携式实用工具包

安装次数: 8,018

依赖关系: 0

建议者: 0

安全性: 0

星标: 21

关注者: 22

分支: 13

开放性问题: 4

类型:cakephp-plugin


README

Build Status

便携式 CakePHP 实用工具包

要求

  • PHP 5.4 或更高版本
  • CakePHP 2.x

辅助工具

  • CsvHelper
  • CkeditorHelper
  • GoogleCalendarHelper
  • TwitterHelper
  • ShareHelper
  • TokeninputHelper
  • TypeheadHelper

行为

  • FileUploadBehavior
  • VersionableBehavior
  • SummableBehavior
  • ThrottleableBehavior
  • EmailableBehavior

模型

  • Throttle

数据源

  • ArraySource
  • Database/MysqlExtended

  • DatabaseCacheEngine - 数据库中的缓存引擎
  • AppTestCase - 扩展 CakeTestCase
  • AppFastFixture - 扩展 TableCopyTestFixture & AppTestFixture (快速且灵活的记录)
  • AppTestFixture - 扩展 CakeTestFixture (灵活的记录)
  • Re
  • Pluck
  • Base62
  • PhpTidy
  • ElasticSearchRequest - 与 ElasticSearch (HttpSocket) 交互

Shell

  • DoShell - 从命令行运行任何 Model.method
  • FixtureUpdateShell - 更新所有 fixture 字段而不触及记录

ShareHelper

无需添加任何 JavaScript API 到您的页面,即可轻松添加分享按钮,支持 googleplus、twitter、facebook 和 pinterest。选项有 urltextimage(并非每个社交网络都支持)

public $helpers = array('Icing.Share');

//some view.ctp
echo $this->Share->twitter(array(
	'text' => 'Check this out'
));
echo $this->Share->facebook();
echo $this->Share->pinterest(array(
	'image' => 'http://example.com/image.png',
	'text' => 'Awesome image'
));
echo $this->Share->googleplus(array(
	'url' => 'http://example.com'
));

CsvHelper

轻松创建和托管 CSV 文件。

//some view.ctp with $data of a model
foreach($data as $record){
	$row = array_values($record['Model']);
	$this->Csv->addRow($row);
}
echo $this->Csv->render('filename.csv');

CkeditorHelper

轻松将 Ckeditors 添加到您的表单中。易于与 Ckfinder 集成

echo $this->Ckeditor->replace('ContentBody', array('ckfinder' => true, 'forcePasteAsPlainText' => 'true'));

GoogleCalendarHelper

创建提醒链接和快速添加表单,以集成到已登录的 Google 日历用户。

public $helpers = array('Icing.GoogleCalendar' => array('domain' => 'audiologyholdings.com'));

$this->GoogleCalendar->reminder('small', array(
	'start' => 'Aug 15th, 2013 8:00pm',
	'end' => 'Aug 15th, 2013 9:00pm',
	'title' => 'Test Event',
	'details' => 'Details of Event',
	'location' => 'Albuquerque, NM',
	'add' => array('nurvzy@gmail.com', 'nick.baker@audiologyholdings.com')
));


$this->GoogleCalendar->quickForm('Add', array(
	'input' => array('label' => 'Quick Add'),
	'create' => array('id' => 'customID),
	'submit' => array('class' => 'someClass')
));

TwitterHelper

创建分享、提及和标签按钮

//Config/twitter.php
$config = array(
	'Twitter' => array(
		'handle' => 'WebTechNick',
		'locale' => 'en',
		'buffer' => true,
	)
);

public $helpers = array('Icing.Twitter' => array(
	'handle' => 'WebTechNick',
	'locale' => 'en',
	'buffer' => true,
));

<?php echo $this->Twitter->share(); ?>
<?php echo $this->Twitter->share('Tweet This!', '/pledge', array('text' => 'Take the hearing health pledge!')); ?>
<?php echo $this->Twitter->share('Tweet', array('action' => 'view'), array(
	'text' => 'Take the hearing health pledge!',
	'large' => true,
	'count' => 'none', //'horizontal' (default), 'vertical'
	'hashtags' => array('HashTag1','HashTagh2','HashTag3'),
	'related' => array('HearingAids','WebTechNick')
)); ?>

行为

FileUploadBehavior

根据 app/Plugin/Icing/Config/file_upload.php.default 创建 Config/file_upload.php

附加到任何模型以处理上传。附加的模型需要名称、类型和大小字段(可定制)

var $actsAs = array('Icing.FileUpload');

var $actsAs = array(
	'Icing.FileUpload' => array(
		'uploadDir'    			=> WEB_ROOT . DS . 'files',
		'fields'       			=> array('name' => 'file_name', 'type' => 'file_type', 'size' => 'file_size'),
		'allowedTypes' 			=> array('pdf' => array('application/pdf')),
		'required'    			=> false,
		'unique' 						=> false //filenames will overwrite existing files of the same name. (default true)
		'fileNameFunction' 	=> 'sha1' //execute the Sha1 function on a filename before saving it (default false)
	)
)

使用内置的辅助工具在线调整大小和缓存

echo $this->FileUpload->image($image['Upload']['name'], 300); //will resize to 300 px wide and cache to webroot/files/resized by default

VersionableBehavior

附加到任何模型以创建当前状态的版本,在保存时,以便稍后恢复。

  • 当您保存时
  • 我们执行一个查找(可选地包含)以找到此记录的旧/当前(保存之前)数据
  • 我们将旧数据保存到 IcingVersion 记录中 ** 这意味着 IcingVersion.json 是旧数据,无论在创建此版本记录之前存在什么

注意:如果可能的话,IcingVersionable 使用 AuthComponent 记录正在执行保存的用户

安装

将模式运行到您的数据库中,以创建 icing_versions

cake schema create -p Icing

您应该在您的数据库中看到 icing_versions

使用示例

绑定到您想要在保存时自动版本化的模型

默认设置

array(
	'contain'          => array(), //only version the current model
	'versions'         => false,   //unlimited versions
	'minor_timeframe'  => false,   //do not mark for minor versions
	'bind'             => false,   //don't bind versions on find
	'check_identical'  => false,   //does not check if this version is identical to last version
	'ignore_identical' => false,   //ignored since not checking
	'useDbConfig'      => null,    //if not set, we use the 'default' inherited from AppModel
)

public $actsAs = array('Icing.Versionable'); // uses default settings

public $actsAs = array('Icing.Versionable' => array(
	'contain'          => array('Hour'), //contains for relative model to be included in the version.
	'versions'         => '5',           //how many version to save at any given time (false by default unlimited)
	'minor_timeframe'  => '10',          //Mark all previous versions if saved within 10 seconds of current version.  Easily cleanup minor_versions
	'bind'             => true,         //if true, attach IcingVersionable as HasMany relationship for you onFind and if contained
	'check_identical'  => true,         //if true, version is marked as minor, if the data is identical to last version
	'ignore_identical' => true,         //if true, no version is created, if the data is identical to last version
	'useDbConfig'      => 'archive'     //optionally you can setup a custom config in app/Config/database.php (ignored when testing)
));

从版本中恢复

$this->Model->restoreVersion('50537471-ba08-44ae-a606-24e5e017215a'); //restores version id 50537471-ba08-44ae-a606-24e5e017215a
$this->Model->restoreVersion('50537471-ba08-44ae-a606-24e5e017215a', false); //restores version id 50537471-ba08-44ae-a606-24e5e017215a and won't create a new version before restoring.
$this->Model->restoreVersion(2, 3); //restores the second version back from most recent on Model id 3
$this->Model->restoreVersion(2, 3, false); //restores the second version back from most recent on Model id 3 and doesn't create a new version before saving

版本之间的差异

$result = $this->Model->diffVersion('50537471-ba08-44ae-a606-24e5e017215a'); //Gets the diff between version id and the curent state of the record.
$result = $this->Model->diffVersion('50537471-ba08-44ae-a606-24e5e017215a', '501234121-ba08-44ae-a606-2asdf767a'); //Gets the diff between two different versions.

保存而不创建版本

$this->Model->save($data, array('create_version' => false));

专业提示

IcingVersionable 将“旧数据”存储在您的模型中,作为 $this->Model->getDataBeforeSave()

因此,如果您想在 afterSave() 中对旧记录进行任何复杂的操作(如比较以查看已更改的内容),它已经为您准备好了... (我们无论如何都需要找到它来保存版本,所以不妨为您提供轻松访问它的途径)

数据源

ArraySource

允许使用数组数据集而不是 SQL 数据库,但可以使用正常的 CakePHP 关联和查找与其他模型数据关联。

示例

//Config/database.php
var $array = array(
	'datasource' => 'Icing.ArraySource'
);

//Model/ConsumerGuide.php
App::uses('AppModel','Model');
class ConsumerGuide extends AppModel {
	public $name = 'ConsumerGuide';
	public $useDbConfig = 'array';
	public $displayField = 'name';
	public $primaryKey = 'type';

	public $records = array(
		array(
			'type' => 'loved_one',
			'text' => "Do you have a loved one with hearing loss and don't know where to turn? Download our free guide, which will give you the information you need to help your family member or friend with hearing loss.",
			'path' => 'Free_Guide_-_Hearing_and_Your_Loved_Ones.pdf',
			'name' => 'Free Guide - Hearing and Your Loved Ones',
			'thumb' => 'hearing_and_your_loved_ones.png',
		),
	);
}

//Example Uses
$this->ConsumerGuide->find('first');
$this->ConsumerGuide->find('all', array(
	'conditions' => array(
		'ConsumerGuide.type' => 'loved_one',
	),
	'fields' => array('ConsumerGuide.text','ConsumerGuide.path'),
	'order' => array('ConsumerGuide.name ASC'),
	'limit' => 2,
));
$this->ConsumerGuide->field('path', array('ConsumerGuide.type' => 'loved_one'));
$this->ConsumerGuide->findByType('loved_one');

Database/MysqlExtended

您是否曾经因为没有更多的列类型而感到沮丧?是否缺少 smallint,或者想要一个 longblob

更改您的 app/Config/database.php

from:
'datasource' => 'Database/Mysql',
to:
'datasource' => 'Icing.Database/MysqlExtended',

现在您可以使用以下“新”类型

  • '二进制' => array('name' => '二进制'),
  • 'blob' => array('name' => 'blob'),
  • 'longblob' => array('name' => 'longblob'),
  • 'tinyint' => array('name' => 'tinyint', 'limit' => '3', 'formatter' => 'intval'),
  • 'smallint' => array('name' => 'smallint', 'limit' => '6', 'formatter' => 'intval'),
  • 'mediumint' => array('name' => 'mediumint', 'limit' => '8', 'formatter' => 'intval'),

这些类型将与所有现有的CakePHP模式工具一起工作,包括 CakeDC Migrations,用于生成新的模式文件,以及从模式文件创建/修改您的数据库。

ThrottleableBehavior

这是Throttle模型上功能的一个方便快捷方式。基本上,这是一个非常干净和简单的限制任何内容的方法。

// setup in the model Behaviors all the time
public $actsAs = array('Icing.Throttleable');

// or load/attach the Behavior
$this->MyModel->Behaviors->load('Icing.Throttleable');

// the default `throttle()` method prefixes the $key with the Model->alias
if (!$this->MyModel->throttle('someKey', 2, 3600)) {
	throw new OutOfBoundsException('This method  on MyModel has been attempted more than 2 times in 1 hour... wait.');
}
// the `_throttle()` method does not modify $key at all, so it's the same regardless of how you access it
if (!$this->MyModel->_throttle('key-could-be-anywhere', 2, 3600)) {
	throw new OutOfBoundsException('This key has been attempted (from somewhere) more than 2 times in 1 hour... wait.');
}

模型

Throttle

简单的限制表/工具集

常见用法

App::uses('Throttle', 'Icing.Model');
if (!ClassRegistry::init('Icing.Throttle')->checkThenRecord('myUniqueKey', 2, 3600)) {
	throw new OutOfBoundsException('This method has been attempted more than 2 times in 1 hour... wait.');
}
if (!ClassRegistry::init('Icing.Throttle')->checkThenRecord('myUniqueKey'.AuthComponent::user('id'), 1, 60)) {
	throw new OutOfBoundsException('A Logged In User Account has attempted more than 1 time in 60 seconds... wait.');
}
if (!ClassRegistry::init('Icing.Throttle')->checkThenRecord('myUniqueKey'.env('REMOTE_ADDR'), 5, 86400)) {
	throw new OutOfBoundsException('Your IP address has attempted more than 5 times in 1 day... wait.');
}
// you can use `limit()` or `checkThenRecord()` -- they are identical methods
if (!ClassRegistry::init('Icing.Throttle')->limit('myUniqueKeyAsLimitAlias', 2, 3600)) {
	throw new OutOfBoundsException('This method has been attempted more than 2 times in 1 hour... wait.');
}

另请参阅ThrottleableBehavior

if (!$this->MyModel->throttle('someKey', 2, 3600)) {
	throw new OutOfBoundsException('This method  on MyModel has been attempted more than 2 times in 1 hour... wait.');
}

主要方法

  • checkThenRecord() - 检查并记录$key的快捷方式
  • limit() - checkThenRecord()的别名
  • check() - 检查是否对于$key没有超过$allowed条记录
  • record() - 为$key保存记录(将$expireInSec过期)
  • purge() - 清空表中所有过期的记录(在check()时自动调用)

单元测试:

./cake test Icing Model/Throttle

DatabaseCacheEngine

Database Cache Engine适用于使用Cache::read/write,但可在多个服务器上使用。

DatabaseCacheEngine 安装

使用MyISAM引擎(适用于存储大量数据)创建database_caches表

CREATE TABLE IF NOT EXISTS `database_caches` (
	`key` varchar(50) NOT NULL,
	`value` text NOT NULL,
	`duration` int(11) unsigned NOT NULL,
	UNIQUE KEY `key` (`key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

如果您不打算存储超过255个字符的json_encoded数据,并且不担心数据库重启时丢失所有缓存,则使用MEMORY引擎将更有利。

CREATE TABLE IF NOT EXISTS `database_caches` (
	`key` varchar(50) NOT NULL,
	`value` varchar(255) NOT NULL,
	`duration` int(11) unsigned NOT NULL,
	UNIQUE KEY `key` (`key`)
) ENGINE=MEMORY DEFAULT CHARSET=utf8;

DatabaseCacheEngine 设置

app/Config/bootstrap.php

CakePlugin::load('Icing');
Cache::config('database', array(
	'engine' => 'Icing.DatabaseCache',
	'duration' => '+1 day',
));

DatabaseCacheEngine 使用

Cache::write('somekey', 'somevalue', 'database');
Cache::read('somekey', 'database');

AppTestCase

自动以分组方式加载固定值。请参阅文件以获取更多使用示例

App::uses('AppTestCase', 'Icing.Lib');
Configure::load('app_test_fixtures');
class WhateverTest extends AppTestCase {
	...
}
  • assertArrayCompare - 比较数组1中的所有键/值与数组2中所有匹配的键及其值。
  • assertInArray - assertTrue(in_array())的快捷方式
  • assertIsEmpty - assertTrue(empty())的快捷方式
  • assertIsNotEmpty - assertTrue(!empty())的快捷方式
  • assertKeyExists - assertTrue(array_key_exists())的快捷方式
  • assertTimestamp - 对时间戳的特殊测试,允许误差范围为期望的时间戳[现在]
  • assertValidationErrors - 对验证错误的特殊测试
  • loadFixtureGroup - 加载一组配置的标准分组固定值

AppFastFixture & AppTestFixture

固定值很糟糕。

以下是一些更好的类,它们使用了一些最佳工具来使它们更容易、更快...

假设

  • 您仍然会将字段和记录放入固定值中
  • 您让您的App的固定值扩展AppFastFixture
  • 您在app/Config/database.php中有一个test配置
  • 您在app/Config/database.php中有一个test_seed配置,它不应与您的生产数据库相同,也不应与您的测试数据库相同。它将被截断并用固定值填充

AppFastFixture

  • 将清理记录以匹配字段(请参阅AppTestFixture)
  • 在初始运行时自动填充test_seed
  • 在运行时删除字段和记录,因此TableCopyTestFixture使用内置的、更快的“从MySQL复制”功能

AppTestFixture

一组工具,可简化固定值的设置

  • 记录不需要包含所有字段(基于类型使用空值)
  • 记录字段不需要按正确顺序排列
  • 记录日期和日期时间字段支持任何strtotime()可解析的值
  • 所有预处理工作都在构造函数__construct()时完成

TableCopyTestFixture

我们使用优秀的lorenzo/cakephp-fixturize插件来加快您的数据集

  • 它支持校验和,只有在表已更改时才重新插入记录(巨大!)
  • 它支持从“种子”数据库创建和插入(更快)

用法

只需扩展AppFastFixtureAppTestFixture (维护旧版本支持)

App::uses('AppFastFixture', 'Icing.Lib');
class UserFixture extends AppFastFixture {

	// OPTIONALY customize these default options
	$this->options = array(
		// fix records to have all the known fields, and only known fields
		'fix' => true,
		// reparse entered dates = date($format, strtotime($value))
		'dates' => true,
		// which db config should you use?
		//   this needs to be setup in app/Config/database.php
		//   set to false to disable
		'sourceConfig' => 'test_seed',
		// fixture name template, used for loading via FixtureManager
		//   sprintf($fixtureName, Inflector::underscore($this->name))
		//   default: sprintf("app.%s", "my_post")
		//   eg: app.my_post
		//   eg: plugin.foobar.foobar_comment
		'fixtureName' => 'app.%s',
	);
	...
}

Re

这是一个非常简单的实用程序库,非常有用。查看源代码单元测试以获取更多信息。

App::uses('Re', 'Icing.Lib');
Re::arrayCSV('a,b,c') ~ Re::stringCSV(array('a', 'b', 'c'));
Re::isValid($data); // basically !empty() but allows 0 (by default)
Re::before($string, ',') == 'all of the string before the first comma';
Re::after($string, '.') == 'all of the string after the last period';

Re::pluck() 已弃用

Re::pluck() 方法基于Set::extract(),而Set::extract()已在CakePHP核心中弃用。虽然我最初非常喜欢XPath语法,但它确实在某些情况下导致的问题比解决的问题更多

切换到Pluck::one()Pluck的其他方法

[DEPRECATED] Re::pluckValid($data, array('/ModelA/field', '/ModelB/field', '/lastChance'), 'defaultValue'); // gets first valid result for various paths or default value
[DEPRECATED] Re::pluck($data, array('/ModelA/field', '/ModelB/field', '/lastChance'), 'defaultValue'); // same as pluckValid() but without the valid check
[DEPRECATED](bool) Re::pluckIsValid($data, array('/ModelA/field', '/ModelB/field', '/lastChance')); // same as pluckValid() and simply returns true/false

Pluck

这是对Hash::extract()方法的简单包装,稍微包含了Hash::filter()方法。

所有这些方法都需要一个数组作为第一个参数

所有这些方法接受多个路径或作为第二个参数的单个路径(顺序很重要)

所有这些方法接受一个filterCallback作为最后一个参数(对于one()firstPathOrDefault()$default是第三个)

  • false不会运行Hash::filter()(重要!,如果您需要空/布尔结果,请使用此选项)
  • null将运行Hash::filter($data)以删除所有空数据
  • 否则将运行Hash::filter($data, $filterCallback)
	Pluck::all() --> array()
		the only real benifit to this is, you can aggregate results from multiple paths
	Pluck::all($user, 'User.id') == array(123)
	Pluck::all($user, array('Bad.path', 'User.id', 'User.name')) == array(123, 'john doe')

	Pluck::firstPath() --> array()
		the first result which matches any path (in order) returns
		note: we do filter data first, so unless you disable filtering, it's the first non-empty result.
	Pluck::firstPath($user, 'User.id') == array(123)
	Pluck::firstPath($user, array('Bad.path', 'User.id', 'User.name')) == array(123)

	Pluck::firstPathOrDefault() --> array() or $default
		the output of Pluck::firstPath()
		if empty, we instead return a $default argument
	Pluck::firstPathOrDefault($user, 'Bad.path', 'default text') == 'default text'
	Pluck::firstPathOrDefault($user, 'Bad.path', array('default', 'array')) == array('default', 'array')

	Pluck::one() --> value {string or whatever} or $default
		the output of Pluck::firstPath()
		but we only return the "current" or first value...
		also, if empty, we instead return a $default argument
	Pluck::one($user, 'User.id') == 123
	Pluck::one($user, array('Bad.path', 'User.id', 'User.name')) == 123
	Pluck::one($user, 'Bad.path', 'non-user') == 'non-user'
		data = string/int/etc = passthrough
	Pluck::one('as_string@example.com', 'User.email', 'no email') == 'as_string@example.com'
	Pluck::one(0, 'User.email', 'no email') == '0'
		data = null or false or empty array or empty string = default
	Pluck::one(array(), 'User.email', 'no email') == 'no email'
	Pluck::one(null, 'User.email', 'no email') == 'no email'
	Pluck::one(false, 'User.email', 'no email') == 'no email'
	Pluck::one('', 'User.email', 'no email') == 'no email'

	Pluck::oneEmpties()
		the same as Pluck::one() but $filterCallback=false, allowing empties

	Pluck::allEmpty()
		the same as (!empty(Pluck::all()))

如果您发现自己正在执行:current(Hash::extract($data, 'User.id')),那么请查看Pluck::one($data, 'User.id')

同样,用多个路径和返回我们在这些路径中找到的第一个有效值。

这是该库的一个相当不错的用例

$user_id = Pluck::one($userOrId, array('User.id', 'Account.user_id', 'user_id', 'id'), 'guest');

如果它是一个有效的ID(非数组,非空),则返回$userOrId

如果$userOrId是一个数组,它将返回从提供的路径中找到的第一个有效结果(左 = 第一/优先)。

如果没有找到有效路径,则返回默认值,默认设置为'guest'(如果没有指定,则为null)。

Base62

将任何(大型)整数转换为Base62,对短URL很有用 - 请参阅单元测试示例

App::uses('Base62', 'Icing.Lib');
Base62::encode(1234567890) == '1ly7vk';

PhpTidy

此库允许您轻松地将文件或内联代码“整理”或“美化”到CakePHP标准/约定。它的“引擎”目前是PhpTidy(尽管我们可能会切换到代码检查器或其他工具)。

这是app/Plugin/Icing/Vendor/phptidy.php脚本的一个便捷包装器

用法

App::uses('PhpTidy', 'Icing.Lib');
$formatted = PhpTidy::string($unformattedPhpCode);
// or //
PhpTidy::string(APP . 'path/to/php-file.php');

ElasticSearchRequest

这是HttpSocket实用程序的扩展,定制和组织以帮助与ElasticSearch交互。

设置

将默认的ElasticSearchIndex配置复制到您的应用程序中,并根据您的设置进行编辑。

cp app/Plugin/Icing/Config/elastic_search_request.php.default app/Config/elastic_search_request.php

请注意,有一个default配置和一个test配置,它将覆盖default配置... 但只有当您的测试设置了以下Configure变量时才会覆盖

Configure::write('inUnitTest', true);

用法

App::uses('ElasticSearchRequest', 'Icing.Lib');
$this->ESR = new ElasticSearchRequest(array('index' => 'myindex', 'table' => 'mytable'));
$records = $this->ESR->search('query string');
$rawResponse = $this->ESR->search('query string', array(), true);
// -------------
$bool = $this->ESR->createIndex('mynewindex');
$mapping = array(
  "test_table" => array(
    "properties" => array(
      "model" => array(
        "type" => "string",
        "store" => "yes",
        ),
      "association_key" => array(
        "type" => "string",
        "store" => "yes",
      ),
      "data" => array(
        "type" => "string",
        "store" => "yes",
      )
    )
  )
);
$bool = $this->ESR->createMapping($mapping);
$data = array(
  "model" => "MyExample",
  "association_key" => "12345",
  "data" => "here is some raw text data, great to search against",
);
$elastic_search_id = $this->ESR->createRecord($data);
$data = $this->ESR->getRecord($elastic_search_id);
$elastic_search_id = $this->ESR->updateRecord($elastic_search_id, $data);
$bool = $this->ESR->deleteRecord($elastic_search_id);
$bool = $this->ESR->deleteIndex('mynewindex');
$mapping = $this->ESR->getMapping();

DoShell

这是一个非常有用的Shell。基本上它只是对您的所有模型方法的简单访问

./cake Icing.do <ModelName> <method> [param1, param2, ...]

因此,如果您的Post模型有一个名为cleanupAllPostsForUser($userId)的方法,您可以从CLI运行它

./cake Icing.do Post cleanupAllPostsForUser 99

它能够访问所有直接和继承的方法,因此您可以使用delete来删除记录123,或使用deleteAll来删除所有记录

./cake Icing.do Post delete 123
./cake Icing.do Post deleteAll 1

或者,您甚至可以尝试传递JSON数据来保存记录

./cake Icing.do -j Post save '{title:"my cli post",body:"this is from the CLI"}'

  • 您可以使用-p <PluginName>参数来加载插件中的模型。
  • 您可以通过传递 -b <行为名称> 参数来自动在模型上加载行为,如果尚未加载的话。
  • 您可以通过传递 -f 参数强制执行方法,即使模型认为它不是一个方法/函数...(对存储过程很有用)
  • 您可以通过传递 -j 参数告知方法您的参数是 JSON 格式。

FixtureUpdateShell

尝试智能更新您的固定装置到

  • 强制它使用 Icing.AppTestFixture
  • 更新 $fields 以始终匹配当前的数据库架构(不会触碰记录或任何其他配置)
  • 对固定装置运行 Icing.PhpTidy,以修正格式

额外功能:它还会验证所有固定装置是否可以在数据库表中找到

用法

./cake Icing.FixtureUpdate
./cake Icing.FixtureUpdate help
./cake Icing.FixtureUpdate --plugin MyPlugin --connection my_connection