How to validate files with Yii2 getInstancesByName uploaded from API? - api

I'm working on a mobile app, the Yii2 is used as backend API, the problem that I can not validate the uploaded files, any idea how I can do it?
public static function uploadPicture ($vid) {
$model = new Pictures ();
$model->load(\Yii::$app->getRequest()->getBodyParams(), '');
$model->vid_image = \yii\web\UploadedFile::getInstancesByName('vid_image');
$imageDir = Yii::$app->params[ 'uploadDir' ];
//if ( $model->validate() AND !empty($model->vid_image) ) { //does not work
if ( !empty($model->vid_image) ) {
foreach ( $model->vid_image as $images => $image) {
$model->name = "t_" . time() . "_i_" . uniqid() . '.' . $image->extension;
$model->vid = $vid;
echo $image->hasError;//return empty
//Yii::$app->end();
//if ( $model->save() and $model->validate() ) { // does not work
if(1==1 and $model->validate()){ // $model->validate() always empty!!!
$image->saveAs($imageDir . '/' . $model->name);
Yii::$app->getResponse()->setStatusCode(201);
$id = implode(',', array_values($model->getPrimaryKey(true)));
Yii::info("[pic.21] image: " . $model->name . " uploaded to: " . $imageDir, __METHOD__);
} elseif ( $model->hasErrors() ) {
$response = \Yii::$app->getResponse();
$response->setStatusCode(500);
throw new ServerErrorHttpException('Failed to create the object for unknown reason. [APIx001]');
}
}
}
return $model;
}
The files are uploaded without validation.
Thanks,

Related

Image upload type for Graphql magento2

Is there any way to upload image using graphql without using base64 format in magento2
public function uploadFile($fileData)
{
// convert base64 string to image and save as file on server.
$uploadedFileName = "";
$fileName = '';
if (isset($fileData['name'])) {
$fileName = $fileData['name'];
} else {
$fileName = rand() . time();
}
if (isset($fileData['filecontent'])) {
$mediaPath = $this->fileSystem->getDirectoryRead(DirectoryList::MEDIA)->getAbsolutePath();
$originalPath = 'ModuleName/Attachments/';
$mediaFullPath = $mediaPath . $originalPath;
if (!file_exists($mediaFullPath)) {
mkdir($mediaFullPath, 0775, true);
}
/* Check File is exist or not */
$fullFilepath = $mediaFullPath . $fileName;
if ($this->fileDriver->isExists($fullFilepath)) {
$fileName = rand() . time() . $fileName;
}
$fileContent = base64_decode($fileData['filecontent']);
$savedFile = fopen($mediaFullPath . $fileName, "wb");
fwrite($savedFile, $fileContent);
fclose($savedFile);
$uploadedFileName = "/" . $fileName ;
}
return $uploadedFileName;
}
See more: https://magento.stackexchange.com/a/351629/101754

update the uploaded file yii2

I have used following to upload image and save it in server and database. Now I want to write a controller to update the uploaded image. how to do it???
controller
public function actionInvitfile()
{
$model = new Applicants();
$imgName = Yii::$app->user->identity->id;
if($model->load(Yii::$app->request->post())){
$model->file = UploadedFile::getInstance($model, 'file');
$model->file->saveAs('uploads/invitfile/' . $imgName . '.' . $model->file->extension);
$model->invitations_file='uploads/invitfile/'. $imgName . '.' . $model->file->extension;
$model->save(false);
}
return $this->goHome();
}
Model
class Applicants extends \yii\db\ActiveRecord
{
public $file;
public static function tableName()
{
return 'applicants';
}
public function rules()
{
return [
[['file'], 'file', 'skipOnEmpty' => true, 'extensions' => 'pdf'],
];
}
Please, Help me!)
I think this can work
public function actionUpdate($id)
{
$imgName = Yii::$app->user->identity->id;
$model = Applicants->findModel($id);
if($model->load(Yii::$app->request->post())){
unlink($model->invitations_file);
$model->file = UploadedFile::getInstance($model, 'file');
$model->file->saveAs('uploads/invitfile/' . $imgName . '.' . $model->file->extension);
$model->invitations_file='uploads/invitfile/'. $imgName . '.' . $model->file->extension;
$model->save(false);
}
return $this->goHome();
}
but here you have official documentation of the kartij blog where you can learn much more and have a better answer to your problem:
http://webtips.krajee.com/advanced-upload-using-yii2-fileinput-widget/
If you want to update a single image, then in update function, before loading post variables, just keep the old image in a variable. The following code will help you:
public function actionUpdate($id)
{
$model = $this->findModel($id);
$oldImage = $model->banner;
if ($model->load(Yii::$app->request->post())) {
//get picture data and save it
$imageFile = \yii\web\UploadedFile::getInstance($model, 'banner');
if($imageFile) {
unlink(Yii::getAlias('#app').'/../../uploads/banners/' . $oldImage);
$fileName = $imageFile->baseName.'_'.time().'.'.$imageFile->extension;
$imageFile->saveAs(Yii::getAlias('#app').'/../../uploads/banners/' . $fileName);
$model->banner = $fileName;
$model->save();
} else {
$model->banner = $oldImage;
$model->save(false);
}
return $this->redirect(['index']);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}

timthumb not working after site migration

I just move my site from xfactorapp.com and any new uploaded picture has no thumbnail. Image is on server but thumbnail is not generated.
How can i change that code to make thumbnail visible from new server?
function href_t`imthumb($file, $set = null, $xf = true) {
if (!$set || !$xf) {
$timthumb = webpath_assets('/timthumb.php');
$href = $timthumb . '?src=' . $file;
if (xcount($set) > 0) {
foreach ($set as $k => $v) {
$href .= '&' . $k . '=' . $v;
}
}
return $href;
} else {
$param['w'] = 150;
$param['h'] = 150;
$param['zc'] = 0;
$param['q'] = 90;
if (DEV) {
$app = DEV_PREFIX . APP_VERSION;
} else {
$app = LIVE_PREFIX . APP_VERSION;
}
if (xcount($set) > 0) {
foreach ($set as $k => $v) {
$param[$k] = $v;
}
$file = '/' . $app . $file;
$protocol = 'http';
if (isSSL()) {
$protocol = 'https';
}
return $protocol . '://thumb.xfactorapp.com/tt/' . implode('/', $param) . $file;
}
}
}
wich give me:
<img class="img-responsive" alt="building" src="http://thumb.xfactorapp.com/tt/263/147/2/90/v3/uploads/_lifttec/cms/58529051881f8f0d87ab1401/5947fffeac28b_200-ATJ-Platforma-autoridicatoare-articulata.jpg">
i wish to change code to take thumbnail with parnam properties but from upload not from thumb.xfactorapp.com
Thanks
Just change $xf from true to false $xf = false.
If you changed server, May be GD Library is missing,So Install and Restart Apache then check your file permission.
// To install GD Library
sudo apt-get install php5.6-gd
// To Restart Apache2
sudo /etc/init.d/apache2 restart

Is there a way to get the last error in php4

PHP 5 has error_get_last. Is there any way to completely or at least partially replicate the same functionality in PHP4.3?
Ripped from the PHP manual (courtesy of php at joert dot net):
<?php
if( !function_exists('error_get_last') ) {
set_error_handler(
create_function(
'$errno,$errstr,$errfile,$errline,$errcontext',
'
global $__error_get_last_retval__;
$__error_get_last_retval__ = array(
\'type\' => $errno,
\'message\' => $errstr,
\'file\' => $errfile,
\'line\' => $errline
);
return false;
'
)
);
function error_get_last() {
global $__error_get_last_retval__;
if( !isset($__error_get_last_retval__) ) {
return null;
}
return $__error_get_last_retval__;
}
}
?>
Yes it is, but you will have to do some programming, you need to attach error handler
$er_handler = set_error_handler("myErrorHandler");
but before this you need to write your "myErrorHandler"
function myErrorHandler($errNumber, $errString, $errFile, $errLine)
{
/*now add it to session so you can access it from anywhere, or if you have class with the static variable you can save it there */
$_SESSION["Error.LastError"] = $errNumber . '<br>' . $errString . '<br>' . $errFile . '<br>' . $errLine;
}
Now when error is occured you can get it by
if(isset($_SESSION["Error.LastError"]))
$str = $_SESSION["Error.LastError"];
now to replicate your method you need to create function
function get_last_error()
{
$str = "";
if(isset($_SESSION["Error.LastError"]))
$str = $_SESSION["Error.LastError"];
return $str;
}

CakePHP Auth Component Using 2 Tables

CakePHP Version 1.2.5
I would like a single user to have multiple email addresses.
I would like a single user to have a single password.
I would like users to log in using any of their multiple email addresses and their single password.
I have created a users table with an id and a password field.
I have created a user_email_addresses table with an id field a user_id field and an email_address field.
Question:
How do I modify the auth component minimally to look for the "username" in this case, "email_address", in the user_email_addresses table and the "password" in the users table?
Seems as though modifying the identify method in the auth component might do it. But I think modifying the auth component directly is a bad idea - any ideas on how to extend and still possibly modify the identify method? http://cakebaker.42dh.com/2009/09/08/extending-cakephps-core-components/ or possibly nominate a different authenticate object?
Starting line 774:
function identify($user = null, $conditions = null) {
if ($conditions === false) {
$conditions = null;
} elseif (is_array($conditions)) {
$conditions = array_merge((array)$this->userScope, $conditions);
} else {
$conditions = $this->userScope;
}
if (empty($user)) {
$user = $this->user();
if (empty($user)) {
return null;
}
} elseif (is_object($user) && is_a($user, 'Model')) {
if (!$user->exists()) {
return null;
}
$user = $user->read();
$user = $user[$this->userModel];
} elseif (is_array($user) && isset($user[$this->userModel])) {
$user = $user[$this->userModel];
}
if (is_array($user) && (isset($user[$this->fields['username']]) || isset($user[$this->userModel . '.' . $this->fields['username']]))) {
if (isset($user[$this->fields['username']]) && !empty($user[$this->fields['username']]) && !empty($user[$this->fields['password']])) {
if (trim($user[$this->fields['username']]) == '=' || trim($user[$this->fields['password']]) == '=') {
return false;
}
$find = array(
$this->userModel.'.'.$this->fields['username'] => $user[$this->fields['username']],
$this->userModel.'.'.$this->fields['password'] => $user[$this->fields['password']]
);
} elseif (isset($user[$this->userModel . '.' . $this->fields['username']]) && !empty($user[$this->userModel . '.' . $this->fields['username']])) {
if (trim($user[$this->userModel . '.' . $this->fields['username']]) == '=' || trim($user[$this->userModel . '.' . $this->fields['password']]) == '=') {
return false;
}
$find = array(
$this->userModel.'.'.$this->fields['username'] => $user[$this->userModel . '.' . $this->fields['username']],
$this->userModel.'.'.$this->fields['password'] => $user[$this->userModel . '.' . $this->fields['password']]
);
} else {
return false;
}
$model =& $this->getModel();
$data = $model->find(array_merge($find, $conditions), null, null, 0);
if (empty($data) || empty($data[$this->userModel])) {
return null;
}
} elseif (!empty($user) && is_string($user)) {
$model =& $this->getModel();
$data = $model->find(array_merge(array($model->escapeField() => $user), $conditions));
if (empty($data) || empty($data[$this->userModel])) {
return null;
}
}
if (!empty($data)) {
if (!empty($data[$this->userModel][$this->fields['password']])) {
unset($data[$this->userModel][$this->fields['password']]);
}
return $data[$this->userModel];
}
return null;
}
AuthComponent::identify() takes two parameters, $user and $conditions
if ($conditions === false) {
$conditions = null;
} elseif (is_array($conditions)) {
$conditions = array_merge((array)$this->userScope, $conditions);
} else {
$conditions = $this->userScope;
}
Looking at the above snippet, if you pass false as the $conditions, the method will execute with no model conditions.
Also, looking at the rest of the code, if you pass a $user value of type string, it won't execute most of the user-related code until it gets here:
} elseif (!empty($user) && is_string($user)) {
$model =& $this->getModel();
$data = $model->find(array_merge(array($model->escapeField() => $user), $conditions));
if (empty($data) || empty($data[$this->userModel])) {
return null;
}
}
Here it runs Model::escapeField(), with no parameters, which returns an escaped version of User.id (by default) and maps this field to the string that was passed in. It then merges this with the $conditions array and performs a Model::find().
It should be safe to say that if the string is the user's ID and there are no conditions it will find the person with that ID every time.
As such, you should be able to extend AuthComponent to do what you want like so:
// app/controllers/components/app_auth.php
<?php
App::import('Component', 'Auth');
class AppAuthComponent extends AuthComponent {
/**
* Custom user identification
*/
function identify($user=null, $conditions=null) {
// get the model AuthComponent is configured to use
$model =& $this->getModel(); // default is User
// do a query that will find a User record when given successful login data
$user = $model->find('first', array('conditions' => array(
'EmailAddress.' . $this->fields['username'] => $user[$this->userModel][$this->fields['username']],
'User.' . $this->fields['password'] => $user[$this->userModel][$this->fields['password']],
));
// return null if user invalid
if (!$user) {
return null; // this is what AuthComponent::identify would return on failure
}
// call original AuthComponent::identify with string for $user and false for $conditions
return parent::identify($user[$this->userModel][$model->primaryKey], false);
}
}
?>
You will have to replace all references to Auth with AppAuth in your application unless you follow this handy tip (the approach in the comments is nice).