How to Create a REST API for Yii2-basic-template - rest

I wanted to create a REST API for a yii2 basic template. I followed the following link.
I created a table named users, a controller named UserController
<?php
namespace app\controllers;
use yii\rest\ActiveController;
class UserController extends ActiveController
{
public $modelClass = 'app\models\User';
}
?>
and in the web
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => 'user'],
],
],
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => '4534',
'parsers' => [
'application/json' => 'yii\web\JsonParser',
],
],
my file name is restapi so i tried this url http://localhost/~user/restapi/web/
all i get is a 404 page not found error. Any help would be appreciated

Rest Api is very simple to to implement in Yii2 basic app. Just follow the steps below. This code is working for me.
application structure
yourapp
+ web
+ config
+ controllers
...
+ api
+ config
+ modules
+ v1
+ controllers
.htaccess
index.php
api/index.php
<?php
// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require(__DIR__ . '/../vendor/autoload.php');
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
// Use a distinct configuration for the API
$config = require(__DIR__ . '/config/api.php');
(new yii\web\Application($config))->run();
api/.htaccess
Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php
api/config/api.php
<?php
$db = require(__DIR__ . '/../../config/db.php');
$params = require(__DIR__ . '/params.php');
$config = [
'id' => 'basic',
'name' => 'TimeTracker',
// Need to get one level up:
'basePath' => dirname(__DIR__).'/..',
'bootstrap' => ['log'],
'components' => [
'request' => [
// Enable JSON Input:
'parsers' => [
'application/json' => 'yii\web\JsonParser',
]
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
// Create API log in the standard log dir
// But in file 'api.log':
'logFile' => '#app/runtime/logs/api.log',
],
],
],
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => ['v1/project','v1/time']],
],
],
'db' => $db,
],
'modules' => [
'v1' => [
'class' => 'app\api\modules\v1\Module',
],
],
'params' => $params,
];
return $config;
api/modules/v1/Module.php
<?php
// Check this namespace:
namespace app\api\modules\v1;
class Module extends \yii\base\Module
{
public function init()
{
parent::init();
// ... other initialization code ...
}
}
api/modules/v1/controllers/ProjectController.php
<?php
namespace app\api\modules\v1\controllers;
use yii\rest\ActiveController;
class ProjectController extends ActiveController
{
// We are using the regular web app modules:
public $modelClass = 'app\models\Project';
}
reference

With those configurations :
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => 'user'],
],
your resources should be available within those urls :
http://localhost/~user/restapi/web/users
http://localhost/~user/restapi/web/users/1
Note: Yii will automatically pluralize controller names for use in endpoints unless you configure the yii\rest\UrlRule::$pluralize property to not do so.
Also you need to configure your server before enabling Pretty Urls by adding a .htaccess file with this content to your web folder if using apache server ( pls refer to link below if using nginx ) :
# Set document root to be "basic/web"
DocumentRoot "path/to/basic/web"
<Directory "path/to/basic/web">
# use mod_rewrite for pretty URL support
RewriteEngine on
# If a directory or a file exists, use the request directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Otherwise forward the request to index.php
RewriteRule . index.php
# ...other settings...
</Directory>
This part wasn't described in the documentation of the link you provided as it was expecting that you did follow the installation & server configuration section :
http://www.yiiframework.com/doc-2.0/guide-start-installation.html#configuring-web-servers

Related

URL-Manager will not route

I cloned our repositorie and created excatly the same URL-rules like at my own project. Now, i will get error like this after having logged in:
Firefox:
Fehler: Umleitungsfehler
The website called is rerouting request,which never will come to an end.
This problem sometimes occures, if cookies are deactivated
Chrome:
ERR_TOO_MANY_REDIRECTS
I definetly accepted using cookies at both browser!!
Debugging shows me,that I have dozen of 302-Requests,so Yii breaks down!
I use Windows, not LINUX, so I don't care about any permissions.
Here are the rules:
'urlManager' => [
'class' => 'yii\web\UrlManager',
'enablePrettyUrl' => true,
'showScriptName' => true,
'enableStrictParsing' => true,
'rules' => [
'/' => 'site/login',
'home' => 'site/index',
'logout' => 'site/logout',
'contact' => 'site/contact',
'signup' => 'site/signup',
'reset' => 'site/request-password-reset',
'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
'<action:(contact|captcha)>' => 'site/<action>'
],
Here is frontend configuration:
<?php
$config = [
// LZA 17-07-30
'sourceLanguage' => 'de-DE',
'language' => 'de-DE',
// LZA 17-07-30 siehe Funktionen in http://demos.krajee.com/grid#module
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => '4lD2RxDNkC4ckpwxTmkDzOLIvk0JMs3F',
],
],
];
if (!YII_ENV_TEST) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = [
'class' => 'yii\debug\Module',
];
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
// LZA 17-07-30 CRUD
'generators' => [// customized CRUD generator
'crud' => [
// 'class' => 'app\myCrud\crud\Generator', // LZA 17-07-20 die Klasse von CRUD generator
'class' => '\common\wsl_dev\wsl_crud\crud\Generator', // LZA 17-07-20 die Klasse von CRUD generator
'templates' => [
'myCrud' => '/#common/wsl_dev/wsl_crud/crud/default', //LZA 17-07-20 Templatename und Templatepfad
]
]
],
// LZA 17-07-30 CRUD
];
}
return $config;
If I deacitvate URLManger,setting
'enablePrettyUrl' => false,
everything works fine.
If I put in manually Url like this:
http://localhost/yii2_perswitch/frontend/web/yiic.php/home
everything works fine,too
Any ideas,how to fix this?
I deleted all my cookies,without any effects!
Solution 1:
Enable debug mode from web/index.php (uncomment these two lines):
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
and you can see exactly what causes the problem.
Redirected too many times error was because the 777 permissions for
runtime and assets folder were not set.
Solution 2:
I think that the problem is related with the path or domain of the cookie. I believe that this info could be useful.
https://github.com/samdark/yii2-cookbook/blob/master/book/cookies.md

Yii 2 redirecting to Login if Guest visit the website

I need some advice how to make redirecting to login if someone does not login into the website and he is only Guest
use Yii;
use \yii\helpers\Url;
if ( Yii::$app->user->isGuest )
return Yii::$app->getResponse()->redirect(array(Url::to(['site/login'],302)));
Use can use it in actions or views , but if you need to use it in lots of actions you probably need look at AccessControl and restrict access even before action is fired
There are two options:
You can use the AccessControl as mentioned by #Maksym Semenykhin
You can use the option below especially when you would like the logged user to be returned to this page after login.
public function beforeAction($action){
if (parent::beforeAction($action)){
if (Yii::$app->user->isGuest){
Yii::$app->user->loginUrl = ['/auth/default/index', 'return' => \Yii::$app->request->url];
return $this->redirect(Yii::$app->user->loginUrl)->send();
}
}}
You can also create a custom 'Controller' class which inherits \yii\web\Controller then have all controllers that need authorization inherit your custom controller.
On the login function, replace the redirect part with the following code:
$return_url = empty(Yii::$app->request->get('return'))? \yii\helpers\Url::to(['/admin/default/index']) :Yii::$app->request->get('return');
return $this->redirect($return_url);
Use the access section to set access to various actions in the controller.
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
'access' => [
'class' => \yii\filters\AccessControl::className(),
'only' => ['create', 'update','index'],
'rules' => [
// deny all POST requests
[
'allow' => false,
'verbs' => ['POST']
],
// allow authenticated users
[
'allow' => true,
'roles' => ['#'],
],
// everything else is denied
],
],
];
}
works for me.
use Yii;
use \yii\helpers\Url;
if ( Yii::$app->user->isGuest )
return Yii::$app->getResponse()->redirect(array(Url::to(['site/login'])));
The Access Control Filter will do the work for you and redirects you to the configured user->loginUrl (config/main.php) if an action is not allowed.
Add the rule:
array('deny',
'users'=>array('?'),
),
To your base controller (f.e. ‘Controller’) where all your controllers are inherited from.
I used index.php in my web/admin directory
This is the sample my index.php
<?php
// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require __DIR__ . '/../../vendor/autoload.php';
require __DIR__ . '/../../vendor/yiisoft/yii2/Yii.php';
$config = require __DIR__ . '/../../config/web.php';
$config["controllerNamespace"]='app\controllers\backend';
(new yii\web\Application($config))->run();
if(Yii::$app->user->isGuest){
$request_headers = apache_request_headers();
$srv=$request_headers['Host'];
header("Location: https://".$srv);
die();
}

Yii2 restful not working

By using this link I tried to have a restful app, but it's not working and always returned this:
Object not found!
The requested URL was not found on this server. If you entered the URL manually please > > check your spelling and try again.
If you think this is a server error, please contact the webmaster.
Error 404
localhost
Apache/2.4.4 (Win32) OpenSSL/1.0.1e PHP/5.5.1
I call it like this: localhost/restful/web/users
Edit:
This kind of call is not working either: localhost/restful/web/?r=users
It returned this:
Not Found (#404)
Page not found.
The above error occurred while the Web server was processing your request.
Please contact us if you think this is a server error. Thank you.
Have the same error (stil getting 404 Not found on each request) have solve it adding .htaccess to (my yii path)/web folder (the same where you have index.php):
# use mod_rewrite for pretty URL support
RewriteEngine on
# If a directory or a file exists, use the request directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Otherwise forward the request to index.php
RewriteRule . index.php
This is because when you create an clean instance of Yii2 you don't have the .htaccess file (in my opinion probably the security reason).
for me the: (enabling curl and using it in my controller) installed via composer
composer require --prefer-dist linslin/yii2-curl "*"
use in controller
<?php
namespace app\controllers;
use yii\rest\ActiveController;
use linslin\yii2\curl;//this was added
class UserController extends ActiveController
{
Don't work.
Maybe this helps someone :)
This is my config/web.php:
<?php
$params = require(__DIR__ . '/params.php');
$config = [
'id' => 'basic',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'components' => [
'urlManager'=>[
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => 'user'],
],
],
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => 'a',
'parsers' => [
'application/json' => 'yii\web\JsonParser',
],
],
'cache' => [
'class' => 'yii\caching\FileCache',
],
'user' => [
'identityClass' => 'app\models\User',
'enableAutoLogin' => true,
],
'errorHandler' => [
'errorAction' => 'site/error',
],
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
// send all mails to a file by default. You have to set
// 'useFileTransport' to false and configure a transport
// for the mailer to send real emails.
'useFileTransport' => true,
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'db' => require(__DIR__ . '/db.php'),
],
'params' => $params,
];
if (YII_ENV_DEV) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = 'yii\debug\Module';
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = 'yii\gii\Module';
}
return $config;
And the controller:
<?php
namespace app\controllers;
use yii\rest\ActiveController;
class UserController extends ActiveController{
public $modelClass = 'app\models\User';
}
Also a created my model by gii.
The problem solved by enabling curl and using it in my controller.

ZF1 Remove 'public/' from url

Using Zend_Navigation, i noticed that it's add '/public/' to all links.
How to remove this addition form url?
$navigation = array(
array(
'label' => 'Home',
'title' => 'Go Home',
'module' => 'default',
'controller' => 'index',
'action' => 'index',
'route' => 'default',
'order' => -100 // make sure home is the first page
),
array(
'label' => 'Test static page!',
'route' => 'pages',
'params' => array(
'permalink' => 'test'
)
)
);
$nav = new Zend_Navigation($navigation);
The solution was simple. Edit your bootsrap.ini like this:
resources.frontController.baseUrl = "/"
Simple way I'm using:
Put index.php to the root directory.
Define APPLICATION_PATH as following:
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/application'));
Run project without public part.
in your .htaccess file you need to add a rule for that,
try following,
RewriteCond %{REQUEST_URI} !/public [NC]
RewriteRule ^(.*)$ public/$1 [L]
add these line in your .htaccess line, and see if it works..
or you can create a virtual host, which directly points to your public directory,
as folllowing,
<VirtualHost *>
ServerAdmin admin#localhost.com
DocumentRoot "C:/wamp/www/project/public"
ServerName localhost.test
ServerAlias localhost.test
<Directory "C:/wamp/www/project/public">
DirectoryIndex index.php
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
you need to follow somethings first in order to create a vhost.
OFFICIAL DOC FOR VIRTUAL HOST

User friendly urls revelsal

Lets say that I want to show http://example.com/topic/view/topicname/thenameofthetopic direclty as http://example.com/thenameofthetopic
So I have achieved that when entering http:// example.com/thenameofthetopic , it redirects you to the controller/action properly, and the website shows what I want to show, the problem is that of course, the URL changed, and I want it to maintain the format http://example.com/thenameofthetopic
Is that possible whitout touching the htaccess file? Just configuring it with yii
How should I do that?
Exactly your case is:
'components' => array(
'urlManager' => array(
'urlFormat' => 'path',
'showScriptName' => false,
'rules' => array(
"<name_of_topic:\w+>/" => 'controller/action'
),
),
)
You will get the name of topic in Yii::app()->request->getQuery('name_of_topic');
htaccess is Yii - classic, the must be present:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L,QSA]
I would advice you to do another way.
'components' => array(
'urlManager' => array(
'urlFormat' => 'path',
'showScriptName' => false,
'rules' => array(
"t/<name_of_topic:\w+>/" => 'controller/action'
),
),
)
So topic link will be http://www.example.com/t/name_of_topic.
This will allow you to use "a//" for articles etc.
One more thing. Read this article to find much interesting things http://www.yiiframework.com/doc/guide/1.1/en/topics.url