Coder Social home page Coder Social logo

restfullyii's People

Contributors

alies-dev avatar arne-s avatar devop avatar drlev avatar eligundry avatar evan108108 avatar galdiolo avatar gplaza avatar grischka avatar jamesmoey avatar jlsalvador avatar kosli avatar lordlele avatar nicdnepr avatar rowasc avatar sheershoff avatar stianlik avatar terales avatar thuey avatar tslater avatar tvandame avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

restfullyii's Issues

Message should not expose CDbCommand-Errors

If there occurs an Error it is possible that the table structure will be exposed like this:

CDbCommand failed to execute the SQL statement: SQLSTATE[23000]: Integrity constraint violation: 1048 Column [...]

While development this is necessary, but in production there should be just an 500. Maybe it would be nice to set some kind of development-flag.

Add content to render, like HATEOAS

Hi,
what's the best practice to add content to a REST request that was not a model attributes?

Like, for example, hypermedia url ( http://en.wikipedia.org/wiki/HATEOAS ).
My working solutions was this, however I'm not sure if it's really a best practice:

In my model I extend this method:

    /**
     * Get attributes
     * @param $names mixed
     * @return array of attributes
     */
    public function getAttributes($names = true) {
        $names = parent::getAttributes($names);
        // If application start as REST, this constant was defined
        if (defined("APPLICATION_REST")) {
            $names['url'] = array(
                'myUrl1'  => Yii::app()->createAbsoluteUrl("api/myController/REST.GET", array('someparam' => somevalue)),
                …
            );
        }
        return $names;
    }

In this way, if application was in REST MODE my model will return an url key with all resource related url (like does github api).

Is this the correct approach?

function isSubresource of ERestSubresourceHelper ,not considering HAS_MANY relation

Hi Evan,once again!
So I have a HAS_MANY relationship : Album HAS_MANY Tracks and I tried to get all the tracks for album with id say 5.
I did GET /api/album/5/tracks and got
404, "Resource Not Found"
After tracing back into your code I found that the problem was in ERestSubresourceHelper.The isSubresource returned false simply because the relation is not MANY_MANY.

 public function isSubresource($model, $subresource_name)
        {        
                if(!array_key_exists($subresource_name, $model->relations())) {
                        return false;
                }
                if($model->relations()[$subresource_name][0] != CActiveRecord::MANY_MANY) {
                        return false;
                }
                return true;
        }

Weird,why no check for HAS MANY?So I replaced the relevant line with

 if(!in_array($model->relations()[$subresource_name][0],array(CActiveRecord::MANY_MANY,CActiveRecord::HAS_MANY))) {
            return false;
        }

and my request immediately returned the expected data.
I don't want to break anything with introducing this line,so I want to make sure I am not missing anything.
Thanks in advance

Not working with MongoYii, also no license declared

Hello, thank you for the extension.

Sadly, it doesn't work with MongoYii extension and it's models, since MongoYii doesn't fully implement an AR interface and has it's criterias in an array form, not class.

I tried to see if I can extend the MongoYii, but it seems that it's more complicated than I can afford.

Another option is to simplify Your extension, which seems a more pragmatic approach to me.

The yiiframework.com says that the extension is distributed under the new BSD license. Can You please add a license file to confirm this?

model.visible.properties and model.hidden.properties not honored in POST, PUT and DELETE

Hi,
I'm trying to hide and show some properties from my model.
All works perfectly in GET request, however this never happen in POST/PUT/DELETE request.

It's a choice by design?
Or the event will never be fired for POST/PUT/DELETE?

I think it will be useful, even for this POST/PUT/DELETE to show the same attributes set as visible and hide those set as hidden.

What do you think?

Filtering:Less than operator not working

Works perfect with every other operator,but triggers 500 Internal Server error with less than (<) or less than or equal operator (<=).See attached files.By the way:Great extension!
Thanks in advance.See attached images.
less_tan_error
biggerthan

Composer package?

Hello guys. I'm just wondering will RESTFullYii ever be available to install via Composer?

How to render into JSON?

Hi there

Continue on the previous issue that I have.

How do render this in JSON?

Here's my current function on normal:

public function actionListByCategory($id)
{

    $dataProvider=new CActiveDataProvider('ad',array(
            'criteria'=>array(
                'order'=>'adid desc',
                'condition'=>'subcatid = '.$id,
            ),
            'pagination'=>array(
                    'pageSize'=>10,
            ),
    ));
    $this->render('index',array(
        'dataProvider'=>$dataProvider,
    ));     
}

So in my restEvent:

public function restEvents()
{
$this->onRest('req.get.listbycategory.render', function($param1) {

        $dataProvider=new CActiveDataProvider('ad',array(
            'criteria'=>array(
                'order'=>'adid desc',
                'condition'=>'subcatid = '.$param1,
            ),
            'pagination'=>array(
                    'pageSize'=>10,
            ),
        ));

        // echo CJSON::encode(['param1'=>$param1]); ????

    });
}

Apologies for this question. Cause I'm still newbie for YiiFramework

Suggestions on filering attributes from output json

We have many fields which are used for internal workflow and validation purpose like moderated by, approved by, modified by, created by etc.

Could you suggest the best elegant way to hide these fields from the API output using RESTFullYii?

Thanks in advance

hidden/visible properties on relation

Currently hidden/visible properties only apply to the current model, but when displaying a model with relations, it would be nice to be able to limit what the relation shows, i.e.

model = Address
{
"city": "Los Angeles",
...

 "user_id": 10,
 "user": {
  //only show name
 }

}

Just like the other request allowing filtering on relations, we could use a dot to specify a hidden/visible relation property, i.e.

    $this->onRest('model.hidden.properties', function()
            {
                return ['user.password'];
            });

truncate for sqlite in tests

Hi.

In tests/migrations/ERestTestMigration.php

To make tests work for sqlite (it took an hour to find out this), it would be better to change execute("TRUNCATE tbl_blabla") lines with truncateTable('tbl_blabla') as below:

$this->execute("TRUNCATE tbl_user");

to

$this->truncateTable('tbl_user');

thanks

Fail to update related records

I'm trying to update a model and its relations. If I pass an empty array to my relation, the save() works fine. But if I pass an array with new records, I receive an error. This error occurs because the plugin tries to set a property of wrong model. Ex:

Suposing that there is a model User with relation_1 and relation_2 (both HAS_MANY)
If I call PUT and pass this array:

$array(
 'name' => 'Hugo',
 'last_name' => 'Campos',
 'relation_1' => array(
  array( 'some_attribute' => 'some_value' ),
  array( 'some_attribute' => 'some_other_value' ),
 ),
 'relation_2' => array(),
)

I receive this:


[body] => {"success":false,"message":"Property \"relation_2.some_attribute\" is not defined.","data":{"errorCode":500}}

404 with PUT

Hi there,

I am getting a 404 (Not Found) when trying to do PUT but not GET or POST.

My config:

'urlManager'=>array(
            'urlFormat'=>'path',
            'class' => 'UrlManager',
            'hostInfo' => 'http://blah.com',
            'secureHostInfo' => 'https://blah.com',
            'secureRoutes' => array(
                //'user/login',   // site/login action
                //'user/registration',  // site/signup action
                //'user/profile/edit',     // all actions of SettingsController
            ),
            'rules'=>require(
                dirname(__FILE__).'/../extensions/starship/restfullyii/config/routes.php'
            ),
),

Controller:


<?php

class PerksController extends Controller
{
    /**
     * @var string the default layout for the views. Defaults to '//layouts/column2', meaning
     * using two-column layout. See 'protected/views/layouts/column2.php'.
     */
    public $layout='//layouts/column2';

    /**
     * @return array action filters
     */
    public function filters()
    {
        return array(
            'accessControl', // perform access control for CRUD operations
             array(
                'ext.starship.RestfullYii.filters.ERestFilter +  REST.GET, REST.PUT, REST.POST, REST.DELETE'
            ),
        );
    }

    public function actions()
    {
            return array(
                'REST.'=>'ext.starship.RestfullYii.actions.ERestActionProvider',
            );
    }

    /**
     * Specifies the access control rules.
     * This method is used by the 'accessControl' filter.
     * @return array access control rules
     */
    public function accessRules()
    {
        return array(
            array('allow',  // allow all users to perform 'index' and 'view' actions
                'actions'=>array('index','view'),
                'users'=>array('@'),
            ),
            array('allow', // allow authenticated user to perform 'create' and 'update' actions
                'actions'=>array('create','update'),
                'users'=>array('@'),
            ),
            array('allow', // allow admin user to perform 'admin' and 'delete' actions
                'actions'=>array('admin','delete'),
                'users'=>array('admin'),
            ),
             array('allow', 'actions'=>array('REST.GET', 'REST.PUT', 'REST.POST', 'REST.DELETE'),
            'users'=>array('*'),
            ),
        );
    }

     public function restEvents()
    {
        $this->onRest('post.filter.req.auth.ajax.user', function($validation) {
            return true;
        });

        $this->onRest('req.post.user.render', function($data) {

            echo CJSON::encode($data);
            //The $data should contain username and password.
            //Login the user here. Should be easy.
            //Then render a response
        });

         $this->onRest('model.with.relations', function($model) {
            $nestedRelations = [];
            return $nestedRelations;
        });
    }

    /**
     * Displays a particular model.
     * @param integer $id the ID of the model to be displayed
     */
    public function actionView($id)
    {
        $this->render('view',array(
            'model'=>$this->loadModel($id),
        ));
    }

    /**
     * Creates a new model.
     * If creation is successful, the browser will be redirected to the 'view' page.
     */
    public function actionCreate()
    {
        $model=new Perks;

        // Uncomment the following line if AJAX validation is needed
        // $this->performAjaxValidation($model);

        if(isset($_POST['Perks']))
        {
            $model->attributes=$_POST['Perks'];
            if($model->save())
                $this->redirect(array('view','id'=>$model->id));
        }

        $this->render('create',array(
            'model'=>$model,
        ));
    }

    /**
     * Updates a particular model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id the ID of the model to be updated
     */
    public function actionUpdate($id)
    {
        $model=$this->loadModel($id);

        // Uncomment the following line if AJAX validation is needed
        // $this->performAjaxValidation($model);

        if(isset($_POST['Perks']))
        {
            $model->attributes=$_POST['Perks'];
            if($model->save())
                $this->redirect(array('view','id'=>$model->id));
        }

        $this->render('update',array(
            'model'=>$model,
        ));
    }

    /**
     * Deletes a particular model.
     * If deletion is successful, the browser will be redirected to the 'admin' page.
     * @param integer $id the ID of the model to be deleted
     */
    public function actionDelete($id)
    {
        $this->loadModel($id)->delete();

        // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
        if(!isset($_GET['ajax']))
            $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));
    }

    /**
     * Lists all models.
     */
    public function actionIndex()
    {
        $dataProvider=new CActiveDataProvider('Perks');
        $this->render('index',array(
            'dataProvider'=>$dataProvider,
        ));
    }

    /**
     * Manages all models.
     */
    public function actionAdmin()
    {
        $model=new Perks('search');
        $model->unsetAttributes();  // clear any default values
        if(isset($_GET['Perks']))
            $model->attributes=$_GET['Perks'];

        $this->render('admin',array(
            'model'=>$model,
        ));
    }

    /**
     * Returns the data model based on the primary key given in the GET variable.
     * If the data model is not found, an HTTP exception will be raised.
     * @param integer $id the ID of the model to be loaded
     * @return Perks the loaded model
     * @throws CHttpException
     */
    public function loadModel($id)
    {
        $model=Perks::model()->findByPk($id);
        if($model===null)
            throw new CHttpException(404,'The requested page does not exist.');
        return $model;
    }

    /**
     * Performs the AJAX validation.
     * @param Perks $model the model to be validated
     */
    protected function performAjaxValidation($model)
    {
        if(isset($_POST['ajax']) && $_POST['ajax']==='perks-form')
        {
            echo CActiveForm::validate($model);
            Yii::app()->end();
        }
    }
}

When I do

(function() {
  var postData = {
    "name": "test",
    "altText": "test",
    "value": "100",
    "disclaimer": "test"
};

  $.ajax({
    url:'/index.php/api/perks',
    data:JSON.stringify(postData),
    type:"POST",
    success:function(data) {
      console.log(data);
    },
    error:function (xhr, ajaxOptions, thrownError){
      console.log(xhr.responseText);
    } 
  });;
})();

I get

{"success":"true","message":"Record Created","data":{"totalCount":"1","perks":{"id":"11","name":"test","altText":"test","value":"100","disclaimer":"test"}}}

Pulling up record:

(function() {
  $.ajax({
    url:'/index.php/api/perks/10',
    type:"GET",
    success:function(data) {
      console.log(data);
    },
    error:function (xhr, ajaxOptions, thrownError){
      console.log(xhr.responseText);
    } 
  });;
})();

I get

{"success":true,"message":"Record Found","data":{"totalCount":1,"perks":{"id":"10","name":"test","altText":"test","value":"100","disclaimer":"test"}}}

But when I try


(function() {
  var postData = {
     "id": "10",
    "name": "test",
    "altText": "test",
    "value": "100",
    "disclaimer": "test"
};

  $.ajax({
    url:'/index.php/api/perks/10',
    data:JSON.stringify(postData),
    type:"PUT",
    success:function(data) {
      console.log(data);
    },
    error:function (xhr, ajaxOptions, thrownError){
      console.log(xhr.responseText);
    } 
  });;
})();

I get

404 - File or directory not found.
The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.

Any ideas? I am new to Yii, so any help would be greatly appreciated! Thanks.

POSTing an Array causes in _composeModelData() a PHP Warning

First of all thanks a lot for you work on the RESTFullYii Extension.

I have a Model representing an Event. There could be many Users to participate on each Event. So I'm trying to POST an Array containing User-IDs on creating an Event.
Content-Type is set to application/json and is POSTed with jQuery.ajax.

This causes:

PHP warning

Invalid argument supplied for foreach()

/var/www/virtual/tbdev/html/dev/topa/teambutler/protected/extensions/restfullyii/components/EActiveRecordRelationBehavior.php(140)

128 }
129 }
130 else
131 $modelData[$key] = $relatedData;
132 }
133 }
134 return $modelData;
135 }
136
137
138 public function setModelAttrs($model, $results, $firstCall=true)
139 {
140 foreach($results as $key=>$val)
141 {
142 if(is_array($val))
143 {
144 $modelName = $model->metaData->relations[$key]->className;
145 $newVal = array();
146 for($i=0; $i<count($val); $i++)
147 {
148 if(isset($val[$i]))
149 $newVal[] = $this->setModelAttrs(new $modelName(), $val[$i], false);
150 else
151 {
152 $newVal = $this->setModelAttrs(new $modelName(), $val, false);

Controller accessRules evaluated before 'req.auth.ajax.user'

Hi,

I'm fairly new to Yii, so maybe I misunderstood something.

In the config/main.php I've created a section like this:

    'params'=>array(
        'RestfullYii' => array(
            'req.auth.ajax.user' => function(){
                if(isset($_SERVER['HTTP_X_REST_USERNAME']) and isset($_SERVER['HTTP_X_REST_PASSWORD'])) {
                    $username = trim($_SERVER['HTTP_X_REST_USERNAME']);
                    $password = trim($_SERVER['HTTP_X_REST_PASSWORD']);
                    $identity=new UserIdentity($username,$password);
                    if($identity->authenticate()){
                        Yii::app()->user->login($identity,0);
                        return true;
                    }
                    else{
                        return false;
                    }
                }
                return false;
            },
        ),      

If I have a controller where the accessRules() function looks like this:

        return array(
            array('allow',
                'actions'=>array('REST.GET','REST.PUT', 'REST.POST', 'REST.DELETE'),
                'users'=>array('*'),
            ),
        );

The req.auth.ajax.user takes care of the authentication. If the X_REST... headers are not present in the request or the user/password is incorrect I got a 401 (Unauthorized) response which is perfect.

BUT

If I have the following in the accessRules() function:

        return array(
            array('allow',
                'actions'=>array('REST.PUT', 'REST.POST', 'REST.DELETE'),
                'roles'=>array('webhd.admin'),
            ),
        );

I'm presented with the Yii default login page.

I did some debugging and I've figured out that the Yii::app()->user->checkAccess() function is called before the 'req.auth.ajax.user' code in the config/main.php so Yii thinks I'm not logged in /which is true/ and redirects me to the login page /which is bad because it is an API and the client side is not rendered here /it's a Single Page App (SPA) written is AngularJS and resides on a different domain and server/

What I'm trying to achieve is to create a pure REST API where the API is totally unaware of the client (no server side rendered login page or redirects only HTTP calls and JSON responses) so I can use my API with a SPA (built with AngularJS) and later I can create other API consumer clients (e.g. Android APP).

First I wanted to do OAuth but I couldn't find any suitable Yii OAuth 2.0 server module where I can implement the Resource Owner Password Flow so I'd like to do some basic auth but I'd like to take advantage of the role based auth mechanism in Yii.

Am I missing something? Am I on the wrong track? Is it even possible without doing some 'magic'? :)

Any help would be appreciated.

Best,
Andras

Why in ERestEventListenerRegistry.php $data variable is CActiveRecord object?

$onRest(ERestEvent::REQ_GET_RESOURCE_RENDER, function($data, $model_name, $relations, $count, $visibleProperties=[], $hiddenProperties=[]) {
            //Handler for GET (single resource) request
            ;$this->setHttpStatus(200);
            $this->renderJSON([
                'type'              => 'rest',
                'success'           => (($count > 0)? true: false),
                'message'           => (($count > 0)? "Record Found": "No Record Found"),
                'totalCount'    => $count,
                'modelName'     => $model_name,
                'relations'     => $relations,
                'visibleProperties' => $visibleProperties,
                'hiddenProperties' => $hiddenProperties,
                'data'              => $data,
            ]);
        });

why $data is CActiveRecord object?
May be $data should be array?

syntax error in example in readme.markdown

In line 2710 of readme.markdown, there is stray closing braces

$this->onRest('post.filter.model.visible.properties', function($result)) {
    return $result; //Array
});

it should be

$this->onRest('post.filter.model.visible.properties', function($result) {
    return $result; //Array
});

model validation

in your saveModel function, I think it's better to put
if(!$models[$i]->validate())
inside the next for.

Because when the condition goes to the first if (in case only one data posted)
if(!isset($data[0])))
then the model will not be validated

Thanks

Disable CWebLogRoute

Shouldn't the CWebLogRoute be disabled when restfullyii is taking care of responses?

At least, when replying with JSON?

CORS and the OPTIONS method 404

I am trying to access my yii site using CORS ( from local host.... ) and am getting a 404 when CORS tries the OPTIONS method. Here is the request / response from Chrome tools:

Request URL:http://www.sullivaniii.com/yii1.1/index.php/api/album
Request Method:OPTIONS
Status Code:404 Not Found

Request Headers
Accept:/
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:x_rest_username, accept, x_rest_password
Access-Control-Request-Method:GET
Connection:keep-alive
Host:www.sullivaniii.com
Origin:http://localhost:8888
Referer:http://localhost:8888/angular/components/angular-seed/app/index.html
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.48 Safari/537.36

Response Headers
Access-Control-Allow-Headers:Content-Type, Authorization,X_REST_USERNAME,X_REST_PASSWORD,X-Requested-With
Access-Control-Allow-Methods:POST,GET,PUT,DELETE,OPTIONS
Access-Control-Allow-Origin:*
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:Keep-Alive
Content-Type:text/html
Date:Sat, 16 Nov 2013 00:00:26 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive:timeout=1, max=150
Pragma:no-cache
Server:Apache/2.2.24 (Unix) mod_hive/3.6 mod_ssl/2.2.24 OpenSSL/0.9.8e-fips-rhel5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 mod_jk/1.2.35
Set-Cookie:PHPSESSID=nks92qnp0ltv9mppkgddlflul3; path=/
Transfer-Encoding:chunked

It looks to me like the access control stuff is correct. Am I missing some configuration of RESTfullyii?

It looks like the site responds, looks for an OPTIONS method, and then fails, defaulting to a 404. Does that seem correct? Is there an OPTIONS method in RESTfullyii?? Not being able to access the site via CORS is a big problem, and when we need the custom headers we also automatically get an OPTIONS request...

self::STAT relations not parsed from model.

Do not know if this is really a bug... When I user parseJson() to render model data and the model has a self::STAT relation, the relation is not being parsed?

example relation I use:

return array(
    'total_planned_hrs'=>array(self::STAT, 'Planned', 'project_id', 'select' => 'SUM(planned_hrs)'),
);

Sub models don't update if current value is null

I have a model "Job" with an id of 1 and a foreign key "type_id"

If the current job.type_id == null and I post the following, nothing happens
{id : 1 , type_id: 1}

If, I however send
{id: 1, type_id: 1, type:{} }

It works perfectly fine. I couldn't figure out what was going on, does anyone have any insight?

Restfullyii With Yii-User

I have yii-user and restfullyii extension installed in my app. I want to send the username and password from the front end(Which is currently angular, and i call web-service using ngResource) to the yii-user extension through the restfullyii.

When i tried to send it, i get 404 error.

Error 404

Unable to resolve the request "user/REST.POST".

i understand that the url i'm trying to post is api/user/login which is not the correct format for the restfullyii, since it expects api/controller. where as in my case i have to call controller inside user extension which is inside modules folder.

How can i route the request to the custom url like api/user/login.

i tried to follow the custom routes of restfullyii. but nothing is working.

i feel this is a common usecase, but i didn't find much help after googling for 2 day. hence i decide to post it here, hoping to get the problem solved.

Can anyone help me to fix it?

If there is a link for reference it will be very useful, not just to me.

Error in saving model

First of all thanks for this extension. I have been using your ext on my project. But then I found an error when saving model. It says that my model doesn't have property id. I think the error occurs because you call id at saveModel function
$ids[] = $models[$cnt]->id;

That will raise an error if the model doesn't have an id property
Thanks in advance.

Overriding model.find.all does not effect totalCount

I tried to modify a event like this.

    $this->criteria = new EMongoCriteria();
    $this->criteria->addCond('_id', 'in', $userIds);
    $this->onRest('model.find.all', function($model) {
        /* @var $model Actor */
        return $model->findAll($this->criteria);
    });

The number of matching docs was 1, but totalCount is still 3 - as if the criteria was ignored when performing the count.

Is this the expected behaviour? Should I have a different approach?

PHP Notice with self::STAT in model

Hi,
I have a Order model with this relation:

'net_total' => array(self::STAT, 'OrderDetail', 'order_id', 'select' => 'SUM(total_no_vat)'),

A really simple relation with SUM of db column.
However, I have a PHP Notice when I try to GET Order with /api/order/1.

The error was:
Trying to get property of non-object
on RestfullYii/widgets/ERestJSONOutputWidget.php(218)

Caused by this call:

RestfullYii/widgets/ERestJSONOutputWidget.php(144): ERestJSONOutputWidget->processAttributes("6500.00", "net_total") 

6500.00 was the value of net_total in this case.

However, I can't understand why a string was used as an object.
The controller has no events or special code, only the default taken from your readme.

For now, I have resolved by removing E_NOTICE from error_reporting, however I think this an issue to address.

Support for Composite Primary Keys

It seems that EActiveRecordRelationBehavior-Class isn't able to handle composite primary keys.
If I try to POST a new Record with a composite primary key the following error occurs:

Array to string conversion

/var/www/virtual/tbdev/html/dev/topa/teambutler/protected/extensions/restfullyii/components/EActiveRecordRelationBehavior.php(112)

100 $this->owner->setAttribute($relation[2], $pk);
101 }
102
103 break;
104 }
105 }
106 }
107
108 //Takes Model and nested relations (Models or Arrays) and returns array.
109 public function _composeModelData($model)
110 {
111 $modelData = $model->attributes;
112 if(empty($model->{$model->tableSchema->primaryKey}))
113 $model->{$model->tableSchema->primaryKey} = null;
114 foreach($model->metadata->relations as $key=>$value)
115 {
116 if($model->hasRelated($key))
117 {
118 if(is_object($model->{$key}))
119 $modelData[$key] = $this->_composeModelData($model->{$key});
120 else if(array_key_exists(0, $model->{$key}))
121 {
122 foreach($model->{$key} as $relatedData)
123 {
124 if(is_object($relatedData))

Is there a quick solution?

Posting a new subresource,do I need a custom route?

Following your team/players example in Subresources section of your readme file,
and assuming I have a MANY_MANY relationship,I 'd like to POST a new player in ,say team 3.Is this possible?I tried
POST /api/team/3/players/ with the new player as payload and got '405', 'Method Not Allowed' exception.After some digging in your code I think this is because a second parameter for the subresource (primary key) is expected,which makes sense if it's a GET,but not with POST obviously since it's a new record.POSTing to a subresource is not covered in this section.
Am I missing something here or should I declare a custom route to handle this ?
Thanks in advance.

Handle model NULL

I think you should also handle when model is null in doRestUpdate and doRestDelete as you did in doRestView.

Thanks

Auto login via api

Hi,

I have successfully implemented the RSTFullYii and the Yii-user module integration. Almost all of the content in my application is only available to authenticated or admin users. For example I want to have only admis (superusers) be able to access member data:

         public function accessRules()
        {
               return array(
                    array('allow',  // allow admin users to perform 'index' and 'view' actions
                        'actions'=>array('index','view'),
                        'users'=>array('admin'),
                    ),
                    array('allow', // allow admin user to perform 'admin' and 'delete' actions
                        'actions'=>array('admin','delete'),
                        'users'=>array('admin'),
                    ),
                     array('allow', 'actions'=>array('REST.GET', 'REST.PUT', 'REST.POST'),
                    'users'=>array('admin'),
                    ),
                    array('deny',  // deny all users
                        'users'=>array('*'),
                    ),
                );
        }

This works fine when I call, while logged in as admin:

$.ajax({
    url:'/index.php/api/appUser/152',
    data:JSON.stringify(postData),
    type:"GET",
    success:function(data) {
      console.log(data);
    },
    error:function (xhr, ajaxOptions, thrownError){
      console.log(xhr.responseText);
    } 
  });

but if I am not logged it I get 403 Forbidden

I need to be able to send in the credentials with the request and have the api available to only admin users from the users module. How can I do that?

Thanks!

POST works, PUT return error when save model with relation

Hi,
I have a Customer model, with a orders relation to Order model.

When I try to POST a new Customer, all works without error.
If I try to update a Customer, I have an error about some Order attributes required.
However, I'm not trying to update or create a Order, only updating a Customer.

There is a way to disable the event afterSave in ERestActiveRecordRelationBehavior?

limit/x/y not working

Hi, when try http://mysite/api/model/limit/x/y returns Unable to resolve the request api/model/limit/x/y

My urlManager config is this:

    'urlManager' => array(
      'urlFormat'=>'path',
      'rules' => array(
        'api/<controller:\w+>' => array(
          '<controller>/restList',
          'verb' => 'GET',
        ),
        'api/<controller:\w+>/<id:\w+>' => array(
          '<controller>/restView',
          'verb' => 'GET',
        ),
        'api/<controller:\w+>/<id:\w+>/<var:\w+>' => array(
          '<controller>/restView',
          'verb' => 'GET',
        ),
        array(
          '<controller>/restUpdate',
          'pattern' => 'api/<controller:\w+>/<id:\d+>',
          'verb' => 'PUT',
        ),
        array(
          '<controller>/restDelete',
          'pattern' => 'api/<controller:\w+>/<id:\d+>',
          'verb' => 'DELETE',
        ),
        array(
          '<controller>/restCreate',
          'pattern' => 'api/<controller:\w+>',
          'verb' => 'POST',
        ),
        array(
          '<controller>/restCreate',
          'pattern' => 'api/<controller:\w+>/<id:\w+>',
          'verb'=>'POST',
        ),
        '<controller:\w+>/<id:\d+>' => '<controller>/view',
        '<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
        '<controller:\w+>/<action:\w+>' => '<controller>/<action>',
      ),
    ),

Thanks for this great extenssion

401 Unauthorized error for custom route

I'm trying to add a custom route that should look like this: (View is my model)

/api/view/config/13

this should call a custom function which executes an elaborated SQL query in the DB.
I keep getting an "Unauthorized" error message because CPhpAuthManager::checkAccess returns false

This is the code I put in place to implement the route:

In ViewController.php I have:

function restEvents(){
...

 $this->onRest('req.get.config.render', function() {

        // TODO retrieve the real viewID
        $view_id = 1;
        $this->getViewConfig($view_id);

    });

}

public function filters()
{
return array(
    'accessControl', // perform access control for CRUD operations
    'postOnly + delete', // we only allow deletion via POST request
    array(
        'RestfullYii.filters.ERestFilter +
        REST.GET, REST.PUT, REST.POST, REST.DELETE'
    ),
);
}


public function accessRules()
{
return array(
    array('allow', 'actions'=>array('REST.GET', 'REST.PUT', 'REST.POST', 'REST.DELETE'),
        'users'=>array('*'),
    ),

...

}

then in config/main.php I have

'params'=>array(
    // this is used in contact page
    'adminEmail'=>'[email protected]',
    'RestfulYii'=>array(
        'req.auth.user'=>function($application_id, $username, $password){
                return false;
            },
    ),
)

I am sure I'm missing something at the level of authorization configuration, but I can't see what it is.

how do i make my functions

HI i am new bee in Yii can you help me in the restapi how i can make the functions which i can use in my url like

http://localhost/jobportal_personal/index.php/api/AppUser/view2

i try to follow the sample code but i dont understand how i make separate functions like
getusers, deleteallusers etc.

also i dont get how this works
$this->onRest('model.instance', function() {
return new Users();
});

any help is really appreciated

Fatal Error

After building and testing a REST implementation on localhost, I moved it to a site. Now, the front page displays fine, and I know I am connecting to the database for logins etc, but when I go to a page that calls one of the models set up for REST (which works fine on localhost) I get this error:

Fatal error: Class 'ERestController' not found in /home/garuda/public_html/www.sullivaniii.com/yii1.1/protected/controllers/AlbumController.php on line 3

My guess is that the components are not loading, but I don't know why... AFAIK the baseUrl is correct - I echoed various means of calling it to the front page.

Any idea why?

Update failed

Thanks for your quick response about the previous issue. Now I found another bug again.
It is in EActiveRecordRelationBehavior class on _composeModelData function line 136.
$modelData[$key] = $relatedData;

it seems that variable $relatedData is not defined before.
The update process failed when data doesn't exist in reference table. For example I have CUSTOMER as a base table and ORDER as reference table. If I have new CUSTOMER data that have no any ORDER, then I want to update the data it will occur an error.
I also wonder how to exclude the relation when updating data.

Thanks

Security filter granularity

In the example there is a way to stop an action based on the verb, i.e. GET, POST, PUT, DELETE but there should be a more user friendly way to provide access control to routes in general (including custom routes and subresources).

For example,

I want to allow:

GET /user/< user_id >
POST /user
GET /user/< user_id >/teams

but disallow:

GET /user/
DELETE /user/
DELETE /user/< user_id >
POST /user/< user_id > /teams

I know some of the examples are explicitly disallowed by the EActionRest classes but there may be more functionality in the future, i.e maintain a relationship from both sides.

Thanks.

Defining Custom Routes

Hi all

I'm very keen with this extension. Currently, I am stuck at the defining custom routes.

I have something like this in my AdController

public function restEvents()
{
$this->emitRest('req.get.listbycategory.render', function($param1) {
echo CJSON::encode(['param1'=>$param1]);
});
}

and also have a definition of the function for listbycategory

public function actionListByCategory($id)
{
$dataProvider=new CActiveDataProvider('ad',array(
'criteria'=>array(
'order'=>'adid desc',
'condition'=>'subcatid = '.$id,
),
'pagination'=>array(
'pageSize'=>10,
//'route'=>'user/login/login',
),
));
$this->render('index',array(
'dataProvider'=>$dataProvider,
));

}

But everytime I execute this via http://localhost:8888/dev-ph-yyy-com/webservice-dev-restful/index.php/api/ad/listbycategory/12

I got this error: {"success":false,"message":"Resource Not Found","data":{"errorCode":404,"message":"Resource Not Found"}}

Any ideas?

Wrong model count

I've noticed in several instances where the model count is not correct, especially if you modify the find.all events.

In the render event why not just use count($models) instead of performing a stat query? The count should really reflect what is being passed as $data and not gathered from another source (although in theory they should match). Plus, doing a simple count() call will save another query execution.

HTTP/1.1 401 Unauthorized

Dear sir,

I have follow up your instruction and I have create a new controller is called UserController and I have added all there functions as you said.

But finally, I got an error HTTP/1.1 401 Unauthorized.

I using CURL in terminal such as bellow:
curl -i -H "Accept: application/json_USERNAME: admin@restuser" -H "X_REST_PASSWORD: admin@Access" http://localhost/cagoapi/api/user

Please let me know what's wrong with this, I should I do next?

Access Web Service from JavaScript & AJAX without cURL

Can I access restfullyii without login to web application?
When I didn't login, I can't access web services

{"success":false,"message":"Unauthorized","data":{"errorCode":401,"message":"Unauthorized"}}

I'm still newbie for YiiFramework, please help me
Thanks

Bind parameters in searches

Hi,

I noticed that the extension does not bind the parameters when doing searches.

For example:

shows a findByPk where the $subresource_pk is included directly on the condition string. This raises some problems. For example, this code blows when the PKs are strings.

These expressions can be easily changed for the following format:

->findByPk($pk, ['condition'=>"$subresource_name.id=:subresource_pk", 'params'=>[':subresource_pk' => $subresource_pk]]);

in order to let Yii properly quote values.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.