How to pass parameters to mainLayoutAsset.php file? - yii2

I have following code in mainLayoutAsset.php file
<?php
/**
* #link http://www.yiiframework.com/
* #copyright Copyright (c) 2008 Yii Software LLC
* #license http://www.yiiframework.com/license/
*/
namespace frontend\assets;
use yii\web\AssetBundle;
/**
* #author Qiang Xue <qiang.xue#gmail.com>
* #since 2.0
*/
class MainLayoutAsset extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
];
public $js = [
'member-area/AdminLTE/app.js',
];
}
Now I want to access params file parameter in to this file
eg.
public $js = [
'member-area/AdminLTE/app.js?v='.Yii::$app->params["version"],
]
but it giving error
PHP Parse Error – yii\base\ErrorException
syntax error, unexpected '.', expecting ']'
'js/tooltip.js?v='.Yii::$app->params["incFileVersion"],

From PHP documentation about class properties :
They are defined by using one of the keywords public, protected, or private, followed by a normal variable declaration. This declaration may include an initialization, but this initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.
http://php.net/manual/en/language.oop5.properties.php
You could simply override init() :
public function init()
{
parent::init();
$this->js = [
'member-area/AdminLTE/app.js?v=' . Yii::$app->params['version'],
];
}
And you should may be try this instead.

Related

PhpStorm has a problem when referencing to a Type named "Resource"

PHPStorm version: 2022.2.3 (Build #PS-222.4345.15, built on October 5, 2022)
I have following class:
<?php declare(strict_types=1);
namespace App\API\Resources;
final class ConfiguredResourceFinder implements ResourceFinder
{
/** #var $resources Resource[] */
private array $resources;
public function find(string $key): Resource
{
foreach ($this->resources as $resource) {
$resource-> // public method suggestion from type Resource not appearing
}
}
}
And following interface in the same namespace:
<?php declare(strict_types=1);
namespace App\API\Resources;
interface Resource
{
public function getKey(): string;
}
When I type $resource->, no method suggestion getKey() is coming.
But when I change the Type, for example to /** #var $resources Foo[] */:
<?php declare(strict_types=1);
namespace App\API\Resources;
interface Foo
{
public function getKey(): string;
}
I receive suggestions:
Any idea why this is not working with the Resource interface? I already invalidated the PhpStorm cache.

FOSRestBundle woes with Symfony4, 204 no content response

I've made a rest controller for Movie objects with a get action.
My database manager one movies with id:3.
When I try to access localhost:8000/api/movie/3 or any other idea for that matter it goes straight back to the page I came from, with only a hint of no content response.
[Tue May 29 16:06:42 2018] 127.0.0.1:61540 [204]: /api/movie/3
I have the following configurations:
services.yaml
services:
...
sensio_framework_extra.view.listener:
alias: Sensio\Bundle\FrameworkExtraBundle\EventListener\TemplateListener
...
routes/rest.yaml
movies:
type: rest
resource: App\Controller\MovieController
prefix: /api
packages/fos_rest.yaml
fos_rest:
param_fetcher_listener: true
allowed_methods_listener: true
routing_loader:
include_format: false
view:
view_response_listener: 'force'
format_listener:
rules:
- { path: '^/api', priorities: ['json'], fallback_format: 'json' }
zone:
- { path: ^/api/* }
packages/framework.yaml:
framework:
...
templating: { engines: ['twig'] }
And the following files:
Controller/MovieController.php
<?php
namespace App\Controller;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Routing\ClassResourceInterface;
use FOS\RestBundle\Controller\FOSRestController;
/**
* #Rest\RouteResource("Movie", pluralize=false)
*/
class MovieController extends FOSRestController implements ClassResourceInterface {
/**
* #Rest\View()
* #Rest\Get("/movie/{id}")
*/
public function getAction(string $id) {}
}
Entity/Movie.php
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\MovieRepository")
*/
class Movie {
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=32)
*/
private $title;
public function __construct($title) {
$this->title = $title;
}
...
}
Debug router is giving me this result:
$ bin/console debug:router | grep movie
get_movie GET ANY ANY /api/movie/{id}
[update]
Due to earlier wrong configurations I encountered the errors:
1
Warning: ReflectionObject::__construct() expects parameter 1 to be object, null given
2
An instance of Symfony\Bundle\FrameworkBundle\Templating\EngineInterface >must be injected in FOS\RestBundle\View\ViewHandler to render templates.
3
Type error: Argument 2 passed to Twig_Environment::render()
must be of the type array
4
There are no registered paths for namespace "FOSRest".
5
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
I had to edit MovieController to return the object or return an exception.
MovieController.php
<?php
namespace App\Controller;
use App\Repository\MovieRepository;
use Doctrine\ORM\EntityManagerInterface;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Routing\ClassResourceInterface;
use FOS\RestBundle\Controller\FOSRestController;
/**
* #Rest\RouteResource("Movie", pluralize=false)
*/
class MovieController extends FOSRestController implements ClassResourceInterface {
/**
* #var EntityManagerInterface
*/
private $entityManager;
/**
* #var MovieRepository
*/
private $movieRepository;
public function __construct(
EntityManagerInterface $entityManager,
MovieRepository $movieRepository
) {
$this->entityManager = $entityManager;
$this->movieRepository = $movieRepository;
}
public function getAction(string $id) {
$movie = $this->movieRepository->find($id);
if($movie === null) {
throw new NotFoundHttpException();
}
return $this->view($movie);
}
}
you should add populateDefaultVars in the view annotation parameters like this :
/**
*
* #rest\View(populateDefaultVars=false)
*/

Having a challenge with Laravel 5.4 requests namespace

I'm trying to reference the Requests class in Laravel, I've tried so many fixes with the keyword "use" but each time I keep getting Reflection exception
that says app\path\specified doesn't exist. I'm confused.
Here is my code:`
<?php
namespace App\Http\Controllers;
//namespace App\Http\Request;
//use Illuminate\Http\Requests;
//use app\Http\Requests\ContactFormRequest;
use App\Message;
use App\Mail\SendMessage;
use Session;
//use App\Requests;
class AboutController extends Controller
{
public function create()
{
return view ('about.contact');
}
public function store(App\Requests\SendMessageRequest $request)
{
$message = $request->message;
Mail::to('myemail')
->send(new SendMessage($message, $request->email,$request->name));
THE REQUESTS CLASS
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class SendMessageRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return false;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
//
'name' => 'required',
'email' => 'required|email',
"message" => 'required',
];
}
}
The commented line(//) are what I've tried
SendMessageRequest is the name of my Request class.
Sorry, I can´t comment your post. However can you also send the SendMessageRequest Class? Is that a subclass of the Request in Laravel?

Share Assets between frontend and backend in Yii2 Advanced template

i've been trying to load a simple CSS (custom.css) from the frontend and backend of my project and I't has been a real pain.
The css is located in:
frontend/views/web/css/custom.css
It loads without problems in the frontend... this is the AppAsset file located in the frontend:
<?php
namespace frontend\assets;
use yii\web\AssetBundle;
/**
* Main frontend application asset bundle.
*/
class AppAsset extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
'css/site.css',
'css/custom.css',
];
public $js = [
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}
So I just thought that the AppAsset file located in backend should look like this:
<?php
namespace frontend\assets;
use yii\web\AssetBundle;
/**
* Main backend application asset bundle.
*/
class AppAsset extends AssetBundle
{
public $basePath = '#webroot';
public $baseUrl = '#web';
public $css = [
'css/custom.css',
];
public $js = [
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}
But all I get when loading the backend index is this:
http://localhost:8888/backend/web/css/custom.cssFailed to load resource: the server responded with a status of 404 (Not Found)
Sorry for the noob question and thanks in advanced. Just want to share a css between frontend and backend.
One direct way to do this is to have a common web accessible folder under app root. Something like /assets, which you can access from both BackEnd and FrontEnd. You would need to edit your .htaccess to allow this as well.
Yii2 will publish assets only if $sourcePath is set, and $basePath and $baseUrl are not set(!)
Therefore:
use yii\web\AssetBundle;
class AppAsset extends AssetBundle
{
public $sourcePath = '#app/assets/app';
public $css = [
'css/openbook.css',
'fontello/css/fontello.css',
'fontello/css/animation.css'
];
public $js = [
'js/plug.openbook.js',
'js/plug.interpret.js',
'js/plug.drop.message.js'
];
public $depends = [
// 'yii\web\YiiAsset',
// 'yii\bootstrap\BootstrapAsset',
];
}
in the main layout:
use frontend\assets\AppAsset;
...
AppAsset::register($this);
If you want to load a share resource i.e js or css , in YourAsset class sourcePath must be "#yourSource/web/",
for example if you want to load a css file in frontend which is located in common/web/css/ directory , your AppAsset or any other custom asset class resides in common/ must have following variables initialize
public $sourcePath = "#common/web";
public $basePath ="#common";
Note : "#ewbroot" path & $baseUrl ="#web" will locate to your current accessing path, in this case it is frontend
& will load it
"localhost/yii-application/frontend/css/filename.css"
so you must omit it.
you can register the file on any view or layout itself
<?php $this->registerCssFile('http://domain.com/frontend/web/path/file.css');?>
or
you can also add the full path in asset bundle
public $css = [
'http://domain.com/frontend/web/path/file.css',
];

Yii2 missing required parameter in a constructor

I've created a new XmlResponseFormatter and now I want to change the rootTag.
class newXmlResponseFormatter extends XmlResponseFormatter
{
/**
* #var string the name of the root element.
*
*/
public $rootTag;
public function __construct($rootTag) {
parent::__construct();
$this->rootTag = $rootTag;
}
}
From a controller I set that value:
$xmlFormater = new newXmlResponseFormatter('newRootTag');
In the controller that value is available, and it sets in $rootTag but it threw the following exception:
exception 'yii\base\InvalidConfigException' with message 'Missing required parameter "rootTag" when instantiating "app\components\override\newXmlResponseFormatter".' in /var/www/html/Admin/vendor/yiisoft/yii2/di/Container.php:451
Does anyone know what can be a problem?
Thanks in advance!
First parameter in XmlResponseFormatter is $config, because XmlResponseFormatter extends Object class. You are violated liskov substitution principle.
You should rewrite your constructor like this:
class newXmlResponseFormatter extends XmlResponseFormatter
{
/**
* #var string the name of the root element.
*
*/
public $rootTag;
/**
* newXmlResponseFormatter constructor.
*
* #param string $rootTag
* #param array $config
*/
public function __construct($rootTag, $config = [])
{
$this->rootTag = $rootTag;
parent::__construct($config);
}
}
In yii2 you should call parent constructor after your code, and call parent init before your code.
$config need for simple configure model like this:
new newXmlResponseFormatter(['rootTag' => 'newRootTag']);