i use laravel 8 components, that according to doc can pass data and use it. but i need some modification passed data as variable that can be used in component
my code got Undefined variable: covers error
<x-item_h :item="$item"/>
item-h.blade.php
<div class="item-h">
{{$item}}
{{$covers}}
</div>
item-h.php
class Item_h extends Component
{
public $item;
public $covers;
public function __construct($item )
{
$this->item = $item;
if ($item->getCover->count() > 0) {
$covers = $item->getCover;
} else {
$covers = $item->artists->getCover;
}
}
public function render()
{
return view('components.item_h');
}
}
so how define variable in component that can be use in it ?
Thanks
First, you need to add covers as when u are calling the component like this.
<x-item_h :item="$item" covers/>
Now update the constructor and add give covers a default value of your choice, so that even u forget to give value to it, it will not crash your view
class Item_h extends Component
{
public $item;
public $covers;
public function __construct($item ,$covers={{REPLACE WITH DEFAULT VALUE}})
{
$this->item = $item;
$this->covers = $covers;
if ($item->getCover->count() > 0) {
$covers = $item->getCover;
} else {
$covers = $item->artists->getCover;
}
}
public function render()
{
return view('components.item_h');
}
}
I am sure this will fix your issue
Related
I am having trouble getting value of the class member setting in another method within the class. I have tried use __get and __set magic methods, getter and setter as well as two more approach as in the code but none of them working.
What I am looking is if the type is U than the javascript variable should be used else not.
Approach one
class UserRatings extends User {
private $postType; // string
public function headJS(){
// access postType value from getItem method
// this outputs nothing (blank)
if ($this->postType = 'U') {
# code...
}
}
public function getItem($post){
$this->postType = $post['data']['post_type'];
$markup = 'html markup to render the output';
return $this->postType;
}
public function isType($post)
{
if ($post == 'U') {
$this->isType = true;
}
return $this->isType;
}
}
Approach two
class UserRatings extends User {
private $isType = false;
public function headJS(){
// even this doesnt't work too
if ($this->isType) {
# code...
}
}
public function getItem($post){
$markup = 'html markup to render the output';
$type = $post['data']['post_type'];
$this->isType($type);
}
public function isType($post)
{
if ($post == 'U') {
$this->isType = true;
}
return $this->isType;
}
}
You first approach will not work as $isType will always be false. Because it’s not initialized and even when you initialize it with your function isType($post) you give it trueas a value. However you check in your headJS() if $this->isType ==‘U’ so always false.
For the second approach everything seems fine. My only guess is that you are calling HeadJS() before isType($post) or the value of $post is always different than ‘U’
you have missed $ sign at $this->isType(type);.
You have to just call $this->headJS(); after $this->isType = true;
class UserRatings extends User {
private $isType = false;
public function headJS(){
// even this doesnt't work too
if ($this->isType) {
# code...
}
}
public function getItem($post){
$markup = 'html markup to render the output';
$type = $post['data']['post_type'];
$this->isType($type);
}
public function isType($post)
{
if ($post == 'U') {
$this->isType = true;
$this->headJS();
}
return $this->isType;
}
}
I have a class that extends from Yii2's Model and I need to declare a class public property in the constructor, but I'm hitting a problem.
When I call
class Test extends \yii\base\Model {
public function __constructor() {
$test = "test_prop";
$this->{$test} = null; // create $this->test_prop;
}
}
Yii tries to call, from what I understand, the getter method of this property, which of course doesn't exist, so I hit this exception.
Also, when I actually do $this->{$test} = null;, this method gets called.
My question is: Is there a way to declare a class public property in another way? Maybe some Reflexion trick?
You could override getter/setter, e.g. :
class Test extends \yii\base\Model
{
private $_attributes = ['test_prop' => null];
public function __get($name)
{
if (array_key_exists($name, $this->_attributes))
return $this->_attributes[$name];
return parent::__get($name);
}
public function __set($name, $value)
{
if (array_key_exists($name, $this->_attributes))
$this->_attributes[$name] = $value;
else parent::__set($name, $value);
}
}
You could also create a behavior...
Ok, I received help from one of Yii's devs. Here is the answer:
class Test extends Model {
private $dynamicFields;
public function __construct() {
$this->dynamicFields = generate_array_of_dynamic_values();
}
public function __set($name, $value) {
if (in_array($name, $this->dynamicFields)) {
$this->dynamicFields[$name] = $value;
} else {
parent::__set($name, $value);
}
}
public function __get($name) {
if (in_array($name, $this->dynamicFields)) {
return $this->dynamicFields[$name];
} else {
return parent::__get($name);
}
}
}
Note that I'm using in_array instead of array_key_exists because the dynamicFields array is a plain array, not an associative one.
EDIT: This is actually wrong. See my accepted answer.
Try to set variable in init method.
Like this:
public function init() {
$test = "test_prop";
$this->{$test} = null; // create $this->test_prop;
parent::init();
}
I'm using Yii and I'm new to it.
I have a default main.php layout file and i need to make some data extractions from DB and cookies.
I've written 2 functions:
public function getRegionId() {
if(isset(Yii::app()->request->cookies['region_id'])) {
$sk = Yii::app()->request->cookies['region_id']->value;
settype($sk,integer);
return $sk;
} else {
return 1;
}
}
public function regionId2region($id) {
if(empty($id) or gettype($id)!=='integer') {
return null;
} else {
$reg = Regions::model()->findAll(array(
'condition'=>"alive=1 AND id=".$id,
));
return $reg;
}
}
Now it is not working in any controller. My question is: is it possible to make functions in the layout file or is there a way to pass data to layout file (so that it displays in all controllers)?
Move methods into Regions model and make it static. Or Create Helper class? contains just static methods.
class RegionHelper {
public static function getRegionId() {
if(isset(Yii::app()->request->cookies['region_id'])) {
return (int)$Yii::app()->request->cookies['region_id']->value;
}
return 1;
}
public static function regionId2region($id) {
if(empty($id) or gettype($id)!=='integer') {
return null;
} else {
$reg = Regions::model()->findAll(array(
'condition'=>"alive=1 AND id=".$id,
));
return $reg;
}
}
}
You can use BeforeAction in your controller, like this:
protected function beforeAction($action) {
//Define your variable here:
public $yourVaribale;
//do your logic and assign any value to variable
}
Now, you can use this variable in the view file:
view:
<h1><?php echo $this->yourVariable; ?></h1>
If your functions are located in the controller that calls the view, you could use the $this reference to access the function. Note the public access of the function.
class UserController extends Controller
{
// :
// :
public function fullName($a,$b) {
return $a.' '.$b;
}
}
...and in your view ...
<h1>Test for <?php echo $this->fullName('Tom', 'Jones'); ?></h1>
If the function is in your model, there are a few choices.
class User extends Activerecord
{
// :
// :
public function fullName($a,$b) {
return $a.' '.$b;
}
}
You could pass the model through the render function,
class UserController extends Controller
{
// :
// :
public function actionDisplayView {
$userModel = User::model()->findByPK(1);
$this->render('user_view', array('model' => $model));
}
}
and directly call the function in the view.
< h1 >Test for <?php echo $model->fullName('Tom', 'Jones'); ?>< / h1 >
or, if you did not pass the function, you could call the function in the view (or helper classes). Watch the scope.
class User extends Activerecord
{
// :
// :
// NOTE: You won't have access to $this.
static public function fullName($a,$b) {
return $a.' '.$b;
}
}
and in the view
< h1 >Test for <?php echo User::fullName('Tom', 'Jones'); ?>< /h1 >
I'm writing the back-end for a website using CodeIgniter. I want to be able to use these two URLs:
(1) website.com/product (to return data on all products)
(2) website.com/product/2 (to return data on product with e.g. ID 2).
I have a Product controller, here is the relevant code in outline:
class Product extends CI_Controller
public function _remap($id = -1)
{
$this->my_function($id)
}
public function my_function($n)
{
if ($n == -1)
{
// Code to return data on all products
}
else
{
// Code to return specific product data
}
}
I'm using _remap() because without it, when the URL is of the form website.com/product/id, codeigniter will want to interpret the id as a method. If the URL is just website.com/product then the $id variable is set to have a default value of -1. But bizarrely this doesn't happen: instead $id is set to the string "index" (I checked this by adding var_dump($id); to the _remap() function).
What is going on?
I would remove the _remap function.
class Product extends CI_Controller {
function __construct(){
parent::__construct();
}
public function index($id = -1)
{
if($id == -1)
{
echo 'full list';
}
else
{
echo 'work on id' . $id;
}
}
}
Then create a route in config/routes.php
$route['product/(:num)'] = 'product/index/$1';
If you really want to use _remap then you'll need to do something like the following:
public function _remap($method, $params = array())
{
if($method == 'index'){
return call_user_func_array(array($this, 'my_function'), $params);
}
}
Well, is there something like before() method in kostache module? For example, if I have a couple of PHP lines inside of the view file, I'd like to execute them separately inside of the view class, without echoing anything in the template itself. How can I handle that?
You can put this type of code in the constructor of your View class. When the view is instantiated, the code will run.
Here is a (slightly modified) example from a working application. This example illustrates a ViewModel that lets you change which mustache file is being used as the site's main layout. In the constructor, it chooses a default layout, which you can override if needed.
Controller:
class Controller_Pages extends Controller
{
public function action_show()
{
$current_page = Model_Page::factory($this->request->param('name'));
if ($current_page == NULL) {
throw new HTTP_Exception_404('Page not found: :page',
array(':page' => $this->request->param('name')));
}
$view = new View_Page;
$view->page_content = $current_page->Content;
$view->title = $current_page->Title;
if (isset($current_page->Layout) && $current_page->Layout !== 'default') {
$view->setLayout($current_page->Layout);
}
$this->response->body($view->render());
}
}
ViewModel:
class View_Page
{
public $title;
public $page_content;
public static $default_layout = 'mytemplate';
private $_layout;
public function __construct()
{
$this->_layout = self::$default_layout;
}
public function setLayout($layout)
{
$this->_layout = $layout;
}
public function render($template = null)
{
if ($this->_layout != null)
{
$renderer = Kostache_Layout::factory($this->_layout);
$this->template_init();
}
else
{
$renderer = Kostache::factory();
}
return $renderer->render($this, $template);
}
}