kohana 3 incorporate file validate in orm - kohana

I cant figure out how to add file validation code to the orm model
As the code is now the text inputs are validated in the orm, but the file has no validation on it at all. I was wondering if it was possible to merge the file validation in the 'profile' model where I have the text validation?
Here is the code in my controller
public function action_public_edit()
{
$content = View::factory('profile/public_edit')
->bind('user', $user)
->bind('profile', $profile)
->bind('errors', $errors);
$user = Auth::instance()->get_user();
$profile = $user->profiles;
$this->template->content = $content;
if ($_POST)
{
if ($profile->values($_POST)->check())
{
$picture = Upload::save($_FILES['profile_picture']);
// Resize, sharpen, and save the image
Image::factory($picture)
->resize(100, 100, Image::WIDTH)
->save();
$profile->profile_picture = basename($picture);
$profile->save();
$redirect = "profile/private";
Request::instance()->redirect($redirect);
}
else
{
$errors = $profile->validate()->errors('profile/public_edit');
}
}
}
And the ORM model
protected $_belongs_to = array('user' => array());
protected $_rules = array(
'first_name' => array(
'not_empty' => NULL,
),
'last_name' => array(
'not_empty' => NULL,
),

You don't need to check() if you save() later - save will do the checking and throw ORM_Validation_Exception if validation is not passed. I suggest to create a function in your model for saving - move the lines after check() to this model. In controller you'll only need to write:
if ($this->request->method() === 'POST')
{
$errors = $profile->upload('profile_picture');
if (empty($errors))
{
try
{
$profile->your_save_function();
$this->request->redirect('profile/private');
}
catch (ORM_Validation_Exception $e)
{
$errors = $e->errors('profile');
}
}
}
In your model:
public function your_save_function()
{
// Do your stuff before uploading the picture
// Save the model
$this->save();
}
public function upload($filename)
{
// Set the default upload directory
Upload::$default_directory = 'your_path';
// Validate the file first
$validation = Validation::factory($_FILES)
->rules($filename, array(
array('not_empty'),
array('Upload::not_empty'),
array('Upload::valid'),
array('Upload::type', array(':value', array('your_valid_extensions'))),
array('Upload::size', array(':value', 'your_max_size')),
));
// Validate and upload OK
if ($validation->check())
{
$picture = Upload::save($_FILES[$filename]);
// Resize, sharpen, and save the image
Image::factory($picture)
->resize(100, 100, Image::WIDTH)
->save();
$this->profile_picture = basename($picture);
}
else
{
return $validation->errors('upload');
}
}
Much simpler and cleaner code.

Related

Codeigniter 4 with drag/drop multiple image uploader, validation

I am using a drag/drop image uploader script with my Codeigniter 4 project and it works well and I can use standard CI4 rules for validating file size, type, etc. but I need to check the max number of files being uploaded. I tried creating a custom rule but the data array does not contain the files. How should this be handled?
Below is test code in my controller when the form is submitted.
public function test_do()
{
helper(['form','url']);
$validation = \Config\Services::validation();
$rules = ['business_images' => ['label' => 'business image(s)',
'rules' => 'validate_images[business_images]']
];
if(!$this->validate($rules))
{
$error = $validation->getError('business_images');
echo 'Error - >'.$error;
}
else
{
echo 'good';
}
}
The image rule class is as follows.
class ImageRules
{
public function validate_images($str, string $fields, array $data, ?string &$error = null): bool
{
if(count($data['business_Images']) > 2)
{
$error = 'Too many files';
return false;
}
return true;
}
}

Import excel in laravel Array key

I am trying to upload the file but when I give import I get the following error Undefined array key "idEvento"
When I handle it by number that I start from scratch I do not get any error and insert into the database
Event Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Eventos extends Model
{
use HasFactory;
protected $fillable = [
'nombre',
'idEvento',
'idSede',
'inicio',
'fin',
'idModalidad',
'cupo',
'valor',
];
}
Import data function
public function importData(Request $request){
$file = $request->file('documento');
$validator = Validator::make(
array(
'file' => $file,
),
array(
'file' => 'file|max:5000|mimes:xlsx,xls',
)
);
if ($validator->fails()) {
return Redirect::to('conferencia/import');
}
$import = new EventosImport();
Excel::import($import, request()->file('documento'));
return view('conferencias.import', ['numRows'=>$import->getRowCount()]);
//return redirect()->to(url('conferencia'));
}
Event import code
<?php
namespace App\Imports;
use App\Models\Eventos;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class EventosImport implements ToModel, WithHeadingRow
{
private $numRows = 0;
/**
* #param array $row
*
* #return \Illuminate\Database\Eloquent\Model|null
*/
public function model(array $row)
{
++$this->numRows;
return new Eventos([
'nombre' => $row['nombre'],
'idEvento' => $row['idEvento'],
'idSede' => $row['idSede'],
'inicio' => \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row['inicio']),
'fin' => \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row['fin']),
'idModalidad' => $row['idModalidad'],
'cupo' => $row['cupo'],
'valor' => $row['valor'],
]);
}
public function getRowCount(): int
{
return $this->numRows;
}
}
Image of the excelenter image description here
it´s better than you use your function import in your controller instead of in your model. To read excel use sometimes similary to:
$data = Excel::load($path, function($reader) {})->get();
if(!empty($data) && $data->count()){
foreach ($data->toArray() as $key => $value) {
if(!empty($value)){
foreach ($value as $v) {
$insert[] = ['title' => $v['title'], 'description' => $v['description']];
}
}
}
if(!empty($insert)){
Item::insert($insert);
return back()->with('success','Insert Record successfully.');
}
}

Always the same view content on slim framework with twig after save changes

I'm using Slim and Twig and I'm trying to change a view content, but it doesn't change after I saved the changes.
This is the controller:
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require '../../vendor/autoload.php';
require './classes/connection.php';
$app = new \Slim\App;
$container = $app->getContainer();
$container['view'] = function ($container) {
$view = new \Slim\Views\Twig('../../views', [
'cache' => '../../views_cache'
]);
// Instantiate and add Slim specific extension
$router = $container->get('router');
$uri = \Slim\Http\Uri::createFromEnvironment(new \Slim\Http\Environment($_SERVER));
$view->addExtension(new \Slim\Views\TwigExtension($router, $uri));
return $view;
};
$app->get('/hello/{name}', function (Request $request, Response $response, array $args) {
/*$name = $args['name'];
$response->getBody()->write("Hello, $name");
echo getcwd();
return $response;*/
return $this->view->render($response, 'login.html', [
'name' => $args['name']
]);
});
$app->post('/login', function (Request $request, Response $response, array $args) {
$post_data = $request->getParsedBody();
if (isset($post_data['user']) && isset($post_data['pass'])) {
$mongo = new Connection();
$conn = $mongo->getConnection();
$collection = $conn->prueba->users;
$result = $collection->find(['user' => $post_data['user']])->toArray();
$dbUser = $result[0]['username'];
$dbPass = $result[0]['password'];
if (password_verify($post_data['pass'], $dbPass)) {
echo '¡La contraseña es válida!';
} else {
echo 'La contraseña no es válida.';
}
} else {
return $response->withJson(array('login_status' => 'ko'));
}
});
$app->run();
What I missed to see the view changes? I think it's something about compile view but I'm not sure. It's the first time I use this framework.

Search filter not working with custom search

I have a search() function in my model and I have messed around a bit with it in order to filter my results with some custom filters. So in my model I have this:
public function search()
{
// #todo Please modify the following code to remove attributes that should not be searched.
$startdate='';
$enddate='';
if ($this->year!=''){
$year=explode('-', $this->year);
$date=DateTime::createFromFormat('Y', $year[0])->format('d/m/Y');
$startdate = General::getSeasonStartDate($date);
$enddate = General::getSeasonEndDate($date);
}
$criteria=new CDbCriteria;
$criteria->with=array(
'contracts'=>array(
'select'=>'contracts.contractdate',
'together'=>true
),
'schoolstudents' => array(
'together' => true,
'select' => false,
),
'schoolstudents.school'
);
//$criteria->order='lastname, firstname, fathername, mothername';
if (Yii::app()->user->CompanyID){
$criteria->compare('school.companyid',Yii::app()->user->CompanyID);
}
if(Yii::app()->user->SchoolID){
$criteria->compare('schoolstudents.schoolid',Yii::app()->user->SchoolID);
}
$criteria->compare('schoolstudents.schoolid', $this->schoolid);
//$criteria->compare('studentid',$this->studentid);
$criteria->compare('lastname',$this->lastname,true);
$criteria->compare('firstname',$this->firstname,true);
$criteria->compare('fathername',$this->fathername,true);
$criteria->compare('telephone1',$this->telephone1,true);
$criteria->compare('telephone2',$this->telephone2,true);
$criteria->compare('cellphone1',$this->cellphone1,true);
$criteria->compare('cellphone2',$this->cellphone2,true);
$criteria->compare('email1',$this->email1,true);
$criteria->compare('email2',$this->email2,true);
if($this->year!=''){
if ($startdate && $enddate){
$from = DateTime::createFromFormat('d/m/Y', $startdate)->format('Y-m-d');
$to = DateTime::createFromFormat('d/m/Y', $enddate)->format('Y-m-d');
if ($this->filter=='R'){
$criteria->addBetweenCondition('contractdate',$from, $to, 'AND');
}
else {
$criteria->addBetweenCondition('schoolstudents.createddate',$from, $to, 'AND');
}
}
} else {
if ($this->filter=='R'){
$criteria->addCondition('contracts.studentid');
} else {
$criteria->addCondition('schoolstudents.studentid');
}
}
if(isset($this->birthdate))
{
if($this->birthdate!='') {
$criteria->addCondition('year(birthdate)=:birthdate');
$criteria->params=CMap::mergeArray($criteria->params,array(
':birthdate'=>$this->birthdate,
)
);
}
}
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'sort'=>array(
'defaultOrder'=>'lastname asc',
),
'pagination'=>array(
'pageSize'=>50,
),
));
}
my controller looks like this:
public function actionAdmin()
{
$model=new Student('search');
$model->unsetAttributes();
$y=date('Y');
$y1=date('Y',strtotime($y.'+1 year'));
$test=$y.'-'.$y1;
$model->year=$test;
$model->filter='A';
if (isset($_GET['Student']['year'])){
$model->year=($_GET['Student']['year']);
}
if (isset($_GET['Student']['filter'])){
$model->filter=$_GET['Student']['filter'];
}
if(isset($_GET['Student']))
$model->attributes=$_GET['Student'];
$this->render('admin',array(
'model'=>$model,
));
}
and my problem is that when I use the search filters provided by Yii they don't work. I don't get an error. They don't return anything. If I remove from search() the extra conditions I've added then the filters work fine. But then I can't use my custom filters. Anybody has any idea how to solve this?Thanks in advance!
Never mind I solved it. I changed my controller to this:
public function actionAdmin()
{
$model=new Student('search');
$model->unsetAttributes();
$y=date('Y');
$y1=date('Y',strtotime($y.'+1 year'));
$test=$y.'-'.$y1;
if (isset($_GET['Student']['year'])){
$model->year=$_GET['Student']['year'];
}
if (isset($_GET['Student']['filter'])){
$model->filter=$_GET['Student']['filter'];
}
if(isset($_GET['Student'])){
$model->attributes=$_GET['Student'];
} else{
//for custom & ajax filters to work together
$model->year=$test;
$model->filter='A';
}
$this->render('admin',array(
'model'=>$model,
));

Kohana ORM Check if user exists and returning messages to View?

I'm using Kohana 3.3 in my project and I'm trying to get the User Registration and Login working. I am using ORM's Auth and Kostache for managing my layout/templates.
How do I:
Check if Username already exists? If it does return to error_msg.mustache a message "User already Exists"
Check if username and email is valid according to my model rules? If not return error message to
error_msg.mustache indicating what validation failed
In my controller I have:
class Controller_User extends Controller {
public function action_signup()
{
$renderer = Kostache_Layout::factory();
$this->response->body($renderer->render(new View_FrontEnd_User, 'frontend/signup'));
}
public function action_createuser()
{
try {
$user = ORM::factory('User');
$user->username = $this->request->post('username');
$user->password = $this->request->post('password');
$user->email = $this->request->post('email');
// How do I:
// Check if Username already exists? If it does return to error_msg.mustache a message "User already Exists"
// Check if email is valid? If not return error message to error_msg.mustache indicating "email is not valid"
$user->save();
}
catch (ORM_Validation_Exception $e)
{
$errors = $e->errors();
}
}
}
In my Model:
<?php
class Model_User extends Model_Auth_User
{
public function rules()
{
return array(
'username' => array(
array('not_empty'),
array('min_length', array(':value', 4)),
array('max_length', array(':value', 32)),
array('regex', array(':value', '/^[-\pL\pN_.]++$/uD')),
),
'email' => array(
array('not_empty'),
array('min_length', array(':value', 4)),
array('max_length', array(':value', 127)),
array('email'),
),
);
}
}
Thanks a lot in advance!
You can do the uniqueness check using Validation and an already-written callback. This has the advantages of keeping your validation logic together, and of being very concise:
public function rules()
{
return array(
'username' => array(
array(array($this, 'unique'), array(':field', ':value')),
// ...
As simple as that!
I originally answered this question with my own solution, which is slightly different from the pre-rolled version, but now that I know about that obviously I'll use it instead of this:
public function rules()
{
return array(
'username' => array(
// ...
array('Model_User::unique_field', array(':field', ':value', $this->pk())),
),
// ...
);
}
public static function unique_field($field, $value, $user_id = NULL)
{
return (ORM::factory('User')->where($field, '=', $value)->find()->pk() === $user_id);
}
Unfortunately I can't help you with the Kostache, but in order to check whether a username already exists you have to actually try and load it:
$user = ORM::factory('User')->where('username', '=', $this->request->post('username'));
if ($user->loaded())
{
// The username already exists
}
You probably want to do this before actually opening the try/catch block.
To use the proper error messages you need to define them in /application/messages folder as described in the ORM Validation guide.

Resources