Edit profile page with 3 tables - Yii frameworks - yii-extensions

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();
}

Related

How to denote a Request Facade by a variable in Laravel?

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:

How to validate two dimensional array in Yii2

How to validate two dimensional array in Yii2.
passenger[0][name] = bell
passenger[0][email] = myemail#test.com
passenger[1][name] = carson123
passenger[1][email] = carson###test.com
how to validate the name and email in this array
Thanks
Probably the most clean solution for validating 2-dimensional array is treating this as array of models. So each array with set of email and name data should be validated separately.
class Passenger extends ActiveRecord {
public function rules() {
return [
[['email', 'name'], 'required'],
[['email'], 'email'],
];
}
}
class PassengersForm extends Model {
/**
* #var Passenger[]
*/
private $passengersModels = [];
public function loadPassengersData($passengersData) {
$this->passengersModels = [];
foreach ($passengersData as $passengerData) {
$model = new Passenger();
$model->setAttributes($passengerData);
$this->passengersModels[] = $model;
}
return !empty($this->passengers);
}
public function validatePassengers() {
foreach ($this->passengersModels as $passenger) {
if (!$passenger->validate()) {
$this->addErrors($passenger->getErrors());
return false;
}
}
return true;
}
}
And in controller:
$model = new PassengersForm();
$model->loadPassengersData(\Yii::$app->request->post('passenger', []));
$isValid = $model->validatePassengers();
You may also use DynamicModel instead of creating Passanger model if you're using it only for validation.
Alternatively you could just create your own validator and use it for each element of array:
public function rules() {
return [
[['passengers'], 'each', 'rule' => [PassengerDataValidator::class]],
];
}
You may also want to read Collecting tabular input section in guide (unfortunately it is still incomplete).

Phalcon query builder can't get joined table data

I have 2 table 'sanpham' and 'danhmuc'. I use phalcon query builder to get data from 2 tables.
$laytin = $this->modelsManager->createBuilder()
->from("sanpham")
->innerJoin('danhmuc','sanpham.danhmuc=danhmuc.sodanhmuc')
->where('sanpham.sosanpham = '.$id.'')
->getQuery()
->getSingleResult();
$breadcrumbs = array('/' => Tool::getTranslation()->_('trangchu'),"/Loai-san-pham/".$laytin->tendep."/".$laytin->sodanhmuc => $laytin->tendanhmuc,'' => $laytin->tieudesanpham );
The query runs, but $laytin->tendep, $laytin->sodanhmuc, $laytin->tendanhmuc in 'danhmuc' table doesn't display. Every column in 'sanpham' table (such as: $laytin->tieudesanpham) displays properly.
You can add specific columns with:
$this->modelsManager->createBuilder()->columns('danhmuc.tend‌​ep, danhmuc.sodanhmuc')
With this method you will have to add each column you want in your output. QueryBuilder docs.
Another method is to query the Sanpham model.
For example:
class Sanpham extends \Phalcon\Mvc\Model
{
public static function findSomething($something)
{
// this is your actual query, it replaces the queryBuilder
return self::query()
->where('sanpham.sosanpham = :id:', ['id' => $something])
->innerJoin('danhmuc', 'sanpham.danhmuc = danhmuc.sodanhmuc')
->execute()->getFirst();
}
public function initialize()
{
// define the relation to danhmuc
$this->belongsTo('danhmuc', 'danhmuc', 'sodanhmuc');
}
}
class Danhmuc extends \Phalcon\Mvc\Model
{
public function initialize()
{
// there are other options besides "hasMany", like "hasOne".
// this is your relation to sanpham
$this->hasMany('sodanhmuc', 'sanpham', 'danhmuc');
}
}
class YourController extends \Phalcon\Mvc\Controller
{
public function testAction()
{
// get your first record in Sanpham matching "12345"
$sanpham = Sanpham::findSomething(12345);
// from your Sanpham object, get the related danhmuc object.
// this works because we defined the relations (belongsTo and hasMany)
$danhmuc = $sanpham->getRelated('danhmuc');
// now you have access to the values of danhmuc via the $danhmuc variable
$breadcrumbs = [
'/' => Tool::getTranslation()->_('trangchu'),
"/Loai-san-pham/" . $danhmuc->tendep => $danhmuc->tendanhmuc,
'' => $danhmuc->tieudesanpham,
];
}
}
Check the Phalcon model docs for more info on this.

phalcon - Relationships not defined when converting resultset to array?

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);
}
}

How do I pass SQL database query from the Model to the Controller and then the View on Code Igniter 2.0.3?

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.