I have a table named uri_table that contain:
id, uri_segment
1, /dir_name/bla-bla-1/
2, /dir_name/bla-bla-2/
3, /dir_name/bla-bla-3/
I want to get the pure link that only contain until controller_name and the controller param are not included. but when I use $_SERVER['URI_SEGMENT'] it will get the controller param too.
so I can't do this code below to search in my model:
function check_uri()
{
$this->db->like('uri_segment',$uri_segment,'after');
$id = $this->db->get('uri_table')->row_array()['id'];
return $id;
}
instead of:
function check_uri($request_uri=$_SERVER['URI_SEGMENT'])
{
//trim controller param that is numeric
for($i = strlen($request_uri)-1;$i > 0;$i--)
{
if(is_numeric($request_uri[$i]) || $request_uri[$i]=='/')
{
continue;
}
else
{
$request_uri = substr($request_uri,0,$i+1);
break;
}
}
$this->db->where('uri_segment',$request_uri);
$id = $this->db->get('uri_table')->row_array()['id'];
return $id;
}
This is my code right now but is also can remove param that is number if the $request_uri = '/dir_name/bla-bla-3/1/some_param/3' it'll return $id null. What can I do to remove the param/get uri without controller param or how to compare the $uri_segment to uri_segment ($this->db->like($uri_segment, '%uri_segment%'))?
Do one thing when you create a controller in that store the controller name like this:
class About extends CI_Controller {
// MVC config
var $PANEL = '';
var $CONTROLLER = 'about';
var $MODEL = 'mdl_about';
var $TITLE = 'page title';
var $LIST_PAGE_NAME = 'aboutus';
function About() {
parent::__construct();
//$this->load->model($this->MODEL, 'model');
}
function index() {
$this->load->view($this->LIST_PAGE_NAME);
}
}
So that above controller, model, page title and view page can be use anywhere is related to that controller.
To display the variable value use like this:
echo $this->CONTROLLER;
Or you can try this:
$this->router->fetch_class(); //for controller
$this->router->fetch_method(); //for method
Related
I am doing some experiment to make my controllers as much dynamic as I can. Let me give you a brief overview. I have a controller Logo Controller which I have set up like this:
use App\Models\Logo;
class LogoController extends Controller
{
public function add(Request $request)
{
$data['entity'] = 'logo';
$newEntityObj = new Logo;
$newEntityObj->title = $title; // set title
$newEntityObj->type = $type; // set type
$saveNewEntityData = $newEntityObj->save(); // save the entity data
------------------
-------------------
}
}
Now I made some changes like:
using a variable to denote the Logo Model.
$modelClass = "App\\Models\\" . ucfirst($data['entity']);
And then, using the $modelClass variable to execution Eloquent actions on it, like this:-
$newEntityObj = new $modelClass;
$newEntityObj->title = $title; // set title
$newEntityObj->type = $type; // set type
$saveNewEntityData = $newEntityObj->save(); // save the entity data
So the Logo Controller Class has been updated to:
use App\Models\Logo;
class LogoController extends Controller
{
public function add(Request $request)
{
$data['entity'] = 'logo';
$modelClass = "App\\Models\\" . ucfirst($data['entity']);
$newEntityObj = new $modelClass;
$newEntityObj->title = $title; // set title
$newEntityObj->type = $type; // set type
$saveNewEntityData = $newEntityObj->save(); // save the entity data
------------------
-------------------
}
}
Now I have created a Validationb Request File to use it for form validation. I am using it like this:
// Request Validation Inclusion //
use App\Http\Requests\AdminRequests\LogoValidation\LogoRequest;
public function add(LogoRequest $request)
{
--------------------------
--------------------------
}
Now instead of writing public function add(LogoRequest $request) I want to make it more dynamic. Something like this:
class LogoController extends Controller
{
public static $classEntity = 'logo';
public static $classFormattedEntity = null;
public static $classRequestVariable = null;
public function __construct()
{
$entityArray = explode('-', str_replace('_', '-', self::$classEntity));
foreach($entityArray as $keyEntity => $rowEntity)
{
if($keyEntity !== 0)
$entityArray[$keyEntity] = ucfirst($rowEntity);
}
self::$classFormattedEntity = implode('', $entityArray);
self::$classRequestVariable = "App\\Http\\Requests\\AdminRequests\\" . ucfirst(self::$classFormattedEntity) . "Validation\\" . ucfirst(self::$classFormattedEntity) . "Request";
}
public function add(self::$classRequestVariable $request)
{
..............................
..............................
}
}
The variable self::$classRequestVariable actually prints App\Http\Requests\AdminRequests\LogoValidation\LogoRequest
But when I am writing public function add(self::$classRequestVariable $request) instead of public function add(LogoRequest $request) I am getting the following error:
I have tested it with 2 methods:
The first:
class ProjectsController extends ControllerBase
{
public function indexAction()
{
$row = array();
$projects = Projects::find();
foreach ($projects as $project) {
foreach($project->employees as $employee){
echo "Employee: " . $employee->name;
}
}
exit;
}
}
Output:
Employee: Admin
The second:
class ProjectsController extends ControllerBase
{
public function indexAction()
{
$row = array();
$projects = Projects::find();
$projects = $projects->toArray();
foreach ($projects as $project) {
foreach($project["employees"] as $employee){
echo $employee->name;
}
}
exit;
}
}
Output:
Notice: Undefined index: employees in app/controllers/ProjectsController.php on line 10
When converting the resultset to array the relationships aren't added to the array, is there a workaround to add it to the array?
The reason I converted the resultset to an array is to edit results for example calculating progress or something like that, without saving it to the database.
Things like this:
foreach($projects as &$project){
//count all the todos.
$todos = Todos::find("project_id = '".$project["id"]."'");
$numberOfTodos = $todos->count();
//count all the todos that are done.
$todos = Todos::find("project_id = '".$project["id"]."' AND status_id = 9");
$numberOfDoneTodos = $todos->count();
$project["percentageDone"] = ($numberOfDoneTodos / $numberOfTodos) * 100;
var_dump($row);exit;
}
$this->view->setVar("projects",$projects);
So I don't have to do calculations on the view side and only have to output it
Yes, when you convert a result set to an array only scalar values are converted.
But for adding a calculated property to your model there's no need to convert it to an array, you can change or create new properties as you wish and it will only be saved to the database when you call for example $project->save() and just properties that match a column name will be stored in the database.
For adding calculated properties I'd recommend you to use the event afterFetch that gets fired for each model retrieved from the database:
class Projects extends \Phalcon\Mvc\Model
{
...
public function afterFetch()
{
//Adds a calculated property when a project is retrieved from the database
$totalTodos = Todos::count("project_id = $this->id");
$completeTodos = Todos::count("project_id = $this->id AND status_id = 9");
$this->percentageDone = round(($completeTodos / $totalTodos) * 100, 2);
}
}
i have created new widget to display information in admin view. Final view must be same as CGridView, but with different logic for columns. Everything works fine, except when i try to call CButtonColumn column.
foreach ($this->columns as $column) {
if (is_array($column) && isset($column['class']) {
$this->renderColumnWidget($column);
}
}
/* ... */
protected function renderColumnWidget($column)
{
$widgetClass = $column->class;
unset($column->class);
if (strpos($widgetClass, '.') === false) {
$widgetClass = 'zii.widgets.grid.'.$widgetClass;
}
$this->widget($widgetClass, $column); // Error from here
}
So basically here i check if there is class attribute in column and call that widget. But i get error: CButtonColumn and its behaviors do not have a method or closure named "run".
What am i doing wrong? CButtonColumn don't have run method, and i don't want to extend this class.
You this as a function like this to initiate your columns
protected function initColumns(){
foreach($this->columns as $i=>$column) {
if(is_string($column))
$column=$this->createDataColumn($column);
else {
if(!isset($column['class']))
$column['class']='CDataColumn';
$column=Yii::createComponent($column, $this);
}
if($column->id===null)
$column->id=$id.'_c'.$i;
$this->columns[$i]=$column;
}
foreach($this->columns as $column)
$column->init();
}
I am new on Yii framework, so please i need some help where to start.
What i need is, action and module to display a form to a user, which his will be able to edit is own profile (with profile picture), so i have 3 table
user_account || user_personal || user_general
how can i build a form that insert and update those 3 table at once?
i try this:
This is what i did, but its still not saving the data even into 1 table.
public function actionUpdate() {
$model = new ProfileUpdate();
if(isset($_POST['ProfileUpdate']))
{
$model->attributes = $_POST['ProfileUpdate'];
if($model->validate())
{
$account = new Profile();
$account->userid = Yii::app()->user->id;
$account->name = $model->name;
$account->website = $model->website;
$account->category = $model->category;
$account->save();
$this->redirect('profile');
}
}
model:
class Profile extends CActiveRecord
{
public $userid;
public $name;
public $website;
public $category;
public static function model()
{
return parent::model(__CLASS__);
}
public function tableName()
{
return 'userinfo';
}
public function primaryKey()
{
return 'id';
}
public static function userExists($user)
{
return self::model()->countByAttributes( array('username'=>$user) ) > 0;
}
}
You can use all three models in a single function
for example:
In create function
$model_account = new user_account;
$model_personal= new user_personal;
$model_general = new user_general;
$this->render('create',array(
'model_account'=>$model_account, 'model_personal' => $model_personal, 'model_general' => $model_general
));
here the all three models pass by render to create page.
in form page you can use the every model attributes as fields
Like this
echo $form->textField($model_account,'account_name');
echo $form->textField($model_personal,'email');
echo $form->textField($model_general,'address');
In create function / Update function
$model_account->attributes = $_POST['user_account'];
$model_personal->attributes = $_POST['user_personal'];
$model_general->attributes = $_POST['user_general'];
if($model_account->validate() && $model_personal->validate() && $model_general->validate())
{
$model_account->save();
$model_personal->save();
$model_general->save();
}
I was trying to pass SQL values from Model to Controller but the value couldn't be passed.
This the code in my model file:
class Has_alert extends CI_Model {
function __construct()
{
parent::__construct();
}
function __get_query() {
$sql = 'alerts_get_alerts';
$query = $this->db->query($sql);
$row = $query->first_row();
$header_data['hasAlert'] = $row->active;
}
}
And this is the code in my controller file:
class Chart extends CI_Controller {
// Default Constructor
public function __construct() {
parent::__construct();
$this->load->helper('html');
$this->load->model('Has_alert', '', TRUE);
$this->Has_alert->__get_query();
//$sql = 'alerts_get_alerts';
//$query = $this->db->query($sql);
//$row = $query->first_row();
//$header_data['hasAlert'] = $row->active;
}
public function index()
{
//Data Arrays
$this->load->helper('html');
$header_data['page_title'] = 'Title';
$header_data['tabid'] = "home";
//Load the headtop.php file and get values from data array
$this->load->view('includes/headertop.php', $header_data);
$this->load->view('homepage');
$this->load->view('includes/newfooter.php');
}
I got this error message on my view file:
A PHP Error was encountered
Severity: Notice
Message: Undefined variable: hasAlert
Filename: includes/headertop.php
Line Number: 184
Does anyone know what the problem is? Thank you.
Model
function __get_query() {
$sql = 'alerts_get_alerts';
$query = $this->db->query($sql);
$row = $query->first_row();
return $row->active;
}
Controller
public function index(){
$this->load->model("Has_alert");
//Data Arrays
$this->load->helper('html');
$header_data['page_title'] = 'Title';
$header_data['tabid'] = "home";
$header_data['hasAlert'] = $this->Has_alert->__get_query();
//Load the headtop.php file and get values from data array
$this->load->view('includes/headertop.php', $header_data);
$this->load->view('homepage');
$this->load->view('includes/newfooter.php');
}
I'm assuming that things like "alerts_get_alerts" is pseudocode.