- open cmd (as an admin)
- type:
mklink /d linkpath targetpath
example:
mklink /d c:\easytoremember c:\users\neil\local\applicationdata\temp\hardtoremember
mklink /d linkpath targetpath
mklink /d c:\easytoremember c:\users\neil\local\applicationdata\temp\hardtoremember
class OCCActiveRecord extends CActiveRecord{
public $checksum = null;
public function afterFind(){
/* get a checksum of all the attribute values after reading a record from db */
$this->checksum = md5(implode('', $this->getAttributes(false)));
parent::afterFind();
}
public function rules(){
/* use an exist validator to make sure that a record with the same checksum is still in db. if it's been modified, then checksums will be different */
return array(
array('id', 'exist', 'message'=>'This record was modified after you read it', 'on'=>'update', 'criteria'=>array('condition'=>'md5(concat('.implode(',',$this->attributeNames()).'))=:checksum', 'params'=>array('checksum'=>$this->checksum)))
);
}
}
Just a rough sketch, but you get the idea. CREATE TABLE `tbl_party` ( `id` int(11) NOT NULL AUTO_INCREMENT, `type` char(1) NOT NULL comment 'p=person,o=organization', `name` varchar(255) NOT NULL comment 'surname if a person', `given_name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ;
class Party extends CActiveRecord {
public static function model($className=__CLASS__){
return parent::model($className);
}
public function tableName(){
return 'tbl_party';
}
public function relations(){
return array(
);
}
public function rules(){
return array(
array('name,type','required'),
array('type','in', 'range'=>array('o','p'))
);
}
}
class Person extends Party {
/* this is required for subtypes */
public static function model($className=__CLASS__){
return parent::model($className);
}
public function defaultScope(){
/* only read Parties that are People */
return array(
'condition'=>"type='p'"
);
}
public function relations(){
/* combine parent and own relations. can have 'People' only relations */
$parentRelations = parent::relations();
$myRelations = array(
);
return array_merge($myRelations, $parentRelations);
}
public function rules(){
/* combine parent and own rules */
$parentRules = parent::rules();
$myRules = array(
array('type', 'default', 'value'=>'p'), /* set type to Person */
array('type', 'in', 'range'=>array('p')), /* allow only Person type */
array('given_name', 'required') /* new rule for this subtype only */
);
/* you want to apply parent rules last, delete them here if necessary */
return array_merge($myRules, $parentRules);
}
}
class Organization extends Party {
public static function model($className=__CLASS__){
return parent::model($className);
}
public function defaultScope(){
return array(
'condition'=>"type='o'"
);
}
public function relations(){
$parentRelations = parent::relations();
$myRelations = array(
);
return array_merge($myRelations, $parentRelations);
}
public function rules(){
$parentRules = parent::rules();
$myRules = array(
array('type', 'default', 'value'=>'o'),
array('type', 'in', 'range'=>array('o'))
);
/* you want to apply parent rules last. delete them if necessary */
return array_merge($myRules, $parentRules);
}
}
public function actionCreate() {//read the post input (use this technique if you have no post variable name):
$post = file_get_contents("php://input");
//decode json post input as php array:
$data = CJSON::decode($post, true);
//contact is a Yii model:
$contact = new Contact();
//load json data into model:
$contact->attributes = $data;
//this is for responding to the client:
$response = array();
//save model, if that fails, get its validation errors:
if ($contact->save() === false) {
$response['success'] = false;
$response['errors'] = $contact->errors;
} else {
$response['success'] = true;
//respond with the saved contact in case the model/db changed any values
$response['contacts'] = $contact;
}
//respond with json content type:
header('Content-type:application/json');
//encode the response as json: echo CJSON::encode($response); //use exit() if in debug mode and don't want to return debug output exit(); }
/**
* takes an array of models and their attributes names and outputs them as json. works with relations unlike CJSON::encode()
* @param $models array an array of models, consider using $dataProvider->getData() here
* @param $attributeNames string a comma delimited list of attribute names to output, for relations use relationName.attributeName
* @return void doesn't return anything, but changes content type to json and outputs json and exits
*/
function json_encode_with_relations(array $models, $attributeNames) {
$attributeNames = explode(',', $attributeNames);
$rows = array(); //the rows to output
foreach ($models as $model) {
$row = array(); //you will be copying in model attribute values to this array
foreach ($attributeNames as $name) {
$name = trim($name); //in case of spaces around commas
$row[$name] = CHtml::value($model, $name); //this function walks the relations
}
$rows[] = $row;
}
header('Content-type:application/json');
echo CJSON::encode($rows);
exit(); //or Yii::app()->end() if you want the log to show in debug mode
}
//usage:
$myModels = $myDataProvider->getData(); //or you can use $model->findAll();
$modelAttributeNames = 'id, subject, body, someStatisticalRelationName, someRelationName.attribute, someRelationName.someOtherRelationName.attribute';
json_encode_with_relations( $myModels, $modelAttributeNames );
<? //load yii framework (you'll likely have to change the path):
require_once( dirname(__FILE__).'/../../yii/framework/yii.php' );
//create the app. note that it does not require a config file, you can just pass in an array:
$app = Yii::createWebApplication( array ( 'basePath' => dirname( __FILE__ ) , // if you don't want Protected folder 'controllerPath' => '' // if you don't want Controllers folder ))->run(); ?>SiteController.php:
<?
class SiteController extends CController
{
public function actionIndex()
{
echo 'hello world';
}
}
?>Now, this doesn't work with Gii or crazy things like assets, but that's probably the smallest Yii installation you can make
var_dump( CPropertyValue::ensureArray( '1,2,a' ) );
/* output: array 0 => string '1,2,3' (length=5) */
var_dump( CPropertyValue::ensureArray( '(1,2,"a")' ) );
/* output:
array
0 => int 1
1=> int 2
2 => string 'a' (length=1)
*/
var_dump( CPropertyValue::ensureBoolean( "TRUE" ) );
/* output: boolean true */
var_dump( CPropertyValue::ensureBoolean( "yii" ) );
/* output: boolean false */
var_dump( CPropertyValue::ensureFloat( "3.9" ) );
/* output: float 3.9 */
var_dump( CPropertyValue::ensureInteger( "3.9" ) );
/* output: int 3 */
var_dump( CPropertyValue::ensureObject( array("a"=>1, "b"=>2) ) );
/* output:
object(stdClass)[53]
public 'a' => int 0
public 'b' => int 1
*/
var_dump( CPropertyValue::ensureString( 5 ) );
/* output: string 5 (length=1) */
ensureEnum ensures that a value is among a list of enumerated values. pass it in a value and a class name that extends CEnumerable and it will throw an error if value is not among the enumerated values. class SortDirection extends CEnumerable
{
const Asc="Asc";
const Desc="Desc";
}
var_dump( CPropertyValue::ensureEnum( "Up" , 'SortDirection' ) );
/* output: throws an error */
var_dump( CPropertyValue::ensureEnum( "Asc" , 'SortDirection' ) );
/* output: string 'Asc' (length=3) */
class Address extends CFormModel /* or CActiveRecord */
{
public $postal_code;
public $street;
public function rules()
{
return array(
//call trim() when validate() is called
array('street', 'filter', 'filter'=>'trim'),
/* call my custom function filterPostalCode when validate() is called
* you can pass it any callback function, but it should only have one parameter
*/
array('postal_code', 'filter', 'filter'=>array( $this, 'filterPostalCode' )),
/* if you are going to filter, then you should put the required validator last, as the validators are called in order */
array('postal_code, street', 'required'),
);
}
public function filterPostalCode($value)
{
//strip out non letters and numbers
$value = preg_replace('/[^A-Za-z0-9]/', '', $value);
return strtoupper($value);
}
}
Usage:$address = new Address; $address->postal_code ="m5w-1e6"; $address->street = " 123 main street "; $address->validate(); echo "$address->street $address->postal_code"; $address->postal_code ="/*-*/*-*/-"; $address->street = " "; $address->validate(); var_dump($address->errors);Output:
array 'postal_code' => array 0 => string 'Postal Code cannot be blank.' (length=28) 'street' => array 0 => string 'Street cannot be blank.' (length=23)
| black(Safe 16 SVG Hex3) #000000 | gray1 #030303 | gray2 #050505 | |||
|---|---|---|---|---|---|
| gray3 #080808 | gray4 #0A0A0A | gray5 #0D0D0D | |||
| gray6 #0F0F0F | gray7 #121212 | gray8 #141414 | |||
| gray9 #171717 | gray10 #1A1A1A | gray11 #1C1C1C | |||
| gray12 #1F1F1F | gray13 #212121 | gray14 #242424 | |||
| gray15 #262626 | gray16 #292929 | gray17 #2B2B2B | |||
| gray18 #2E2E2E | gray19 #303030 | gray20(Safe Hex3) #333333 | |||
| gray21 #363636 | gray22 #383838 | gray23 #3B3B3B | |||
| gray24 #3D3D3D | gray25 #404040 | gray26 #424242 | |||
| gray27 #454545 | gray28 #474747 | gray29 #4A4A4A | |||
| gray30 #4D4D4D | gray31 #4F4F4F | gray32 #525252 | |||
| gray33(Hex3) #555555 | gray34 #575757 | gray35 #595959 | |||
| gray36 #5C5C5C | gray37 #5E5E5E | gray38 #616161 | |||
| gray39 #636363 | gray40(Safe Hex3) #666666 | dimgrey(SVG) #696969 | |||
| dimgray(SVG) #696969 | gray42 #6B6B6B | gray43 #6E6E6E | |||
| gray44 #707070 | gray45 #737373 | gray46 #757575 | |||
| gray47 #787878 | gray48 #7A7A7A | gray49 #7D7D7D | |||
| grey(16 SVG) #808080 | gray50 #7F7F7F | gray(16 SVG) #808080 | |||
| gray51 #828282 | gray52 #858585 | gray53 #878787 | |||
| gray54 #8A8A8A | gray55 #8C8C8C | gray56 #8F8F8F | |||
| gray57 #919191 | gray58 #949494 | gray59 #969696 | |||
| gray60(Safe Hex3) #999999 | gray61 #9C9C9C | gray62 #9E9E9E | |||
| gray63 #A1A1A1 | gray64 #A3A3A3 | gray65 #A6A6A6 | |||
| darkgray(SVG) #A9A9A9 | gray66 #A8A8A8 | darkgrey(SVG) #A9A9A9 | |||
| gray67 #ABABAB | sgilightgray(Hex3) #AAAAAA | gray68 #ADADAD | |||
| gray69 #B0B0B0 | gray70 #B3B3B3 | gray71 #B5B5B5 | |||
| gray72 #B8B8B8 | gray73 #BABABA | gray74 #BDBDBD | |||
| silver(16 SVG) #C0C0C0 | gray #BEBEBE | gray75 #BFBFBF | |||
| gray76 #C2C2C2 | gray77 #C4C4C4 | gray78 #C7C7C7 | |||
| gray79 #C9C9C9 | verylightgrey #CDCDCD | gray80(Safe Hex3) #CCCCCC | |||
| gray81 #CFCFCF | gray82 #D1D1D1 | gray83 #D4D4D4 | |||
| lightgrey(SVG) #D3D3D3 | lightgray(SVG) #D3D3D3 | gray84 #D6D6D6 | |||
| gray85 #D9D9D9 | gainsboro(SVG) #DCDCDC | gray86 #DBDBDB | |||
| gray87 #DEDEDE | gray88 #E0E0E0 | gray89 #E3E3E3 | |||
| gray90 #E5E5E5 | gray91 #E8E8E8 | gray92 #EBEBEB | |||
| gray93 #EDEDED | gray94 #F0F0F0 | gray95 #F2F2F2 | |||
| whitesmoke(SVG) #F5F5F5 | gray97 #F7F7F7 | gray98 #FAFAFA | |||
| gray99 #FCFCFC | white(Safe 16 SVG Hex3) #FFFFFF |
/* use for inline (such as text or images) children */
.hcenter-child
{
text-align:center;
}
/*reset the text align, as it inherits*/
.hcenter-child *
{
text-align:left;
}
/* use for block children (ex divs) */
.hcenter
{
width:96%; /*needs any width other than auto*/
margin-left:auto;
margin-right:auto;
}
.round-borders
{
-moz-border-radius:5px;
-webkit-border-radius:5px;
border-radius:5px;
/*see http://tumble.sneak.co.nz/post/928998513/fixing-the-background-bleed*/
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box;
/*use a behavior file for border radius for IE6-8. see http://www.impressivewebs.com/css3-rounded-corners-in-internet-explorer/ or try the jquery corner plugin */
}
.opacity
{
opacity:.5; /*50%*/
filter:alpha(opacity=50);
zoom:1; /*iefix*/
}