Phalcon MongoDb save - mongodb

I have problem with save method of collections in Phalcon.It doesn't work and doesn't give me any errors or something.I want to create a Micro App with mongoDb:
Phalcon version: 1.3.4
php : 5.5.9
Here are the registered services:
<?php
use Phalcon\DI\FactoryDefault,
Phalcon\Assets\Manager as AssetsManager,
Phalcon\Mvc\Collection\Manager as CollectionManager,
Phalcon\Mvc\View\Simple as View,
Phalcon\Mvc\View\Engine\Volt,
Phalcon\Mvc\Url as UrlResolver,
Phalcon\Flash\Session as Flash,
Phalcon\Flash\Direct as FlashDirect,
Phalcon\Session\Adapter\Files as Session;
$di = new FactoryDefault();
$di['url'] = function () {
$url = new UrlResolver();
$url->setBaseUri('/dasshy/');
return $url;
};
/**
* Flash service with custom CSS classes
*/
$di['flash'] = function () {
return new Flash(array(
'error' => 'alert alert-error',
'success' => 'alert alert-success',
'notice' => 'alert alert-info',
));
};
/**
* Flash service with custom CSS classes
*/
$di['flashDirect'] = function () {
return new FlashDirect(array(
'error' => 'alert alert-error',
'success' => 'alert alert-success',
'notice' => 'alert alert-info',
));
};
$di['session'] = function () {
$session = new Session(array(
'uniqueId' => 'dasshy-'
));
$session->start();
return $session;
};
$di['mongo'] = function () {
$mongo = new MongoClient();
return $mongo->selectDb("stats");
};
$di->set('collectionManager', function () {
return new Phalcon\Mvc\Collection\Manager();
});
I want to use the ODM, so here is the model Collection:
<?php
namespace Dasshy\Models;
class Messages extends \Phalcon\Mvc\Collection
{
public $content;
public $senderId;
public $receiverId;
public $date;
}
And here how i use it at handlers.php:
<?php
use Dasshy\Models\Messages;
use Phalcon\Mvc\Micro\Collection;
$app->map('/send/{receiverId}/{senderId}/{content}', function ($receiverId, $senderId, $content) use ($app) {
$messageModel = new Messages();
$messageModel->receiverId = $receiverId;
$messageModel->senderId = $senderId;
$messageModel->content = $content;
$messageModel->date = date('Y-m-d H-i-s', time());
$messageModel->save();
if ($messageModel->save() == false) {
echo "Umh, We can't store robots right now: \n";
foreach ($messageModel->getMessages() as $message) {
echo $message, "\n";
}
} else {
echo "Great, a new robot was saved successfully!";
}
});
$app->map('/messages', function () use ($app) {
var_dump(Messages::find());
exit;
});

you need to setup the mongo connection on the service...
$config = $di->getShared('config')->mongo;
$connect_data = $config->username . ':' . $config->password . '#' . $config->host . ':' . $config->port . '/' . $config->dbname;
$mongo = new \MongoClient("mongodb://" . $connect_data);
return $mongo->selectDB($config->dbname);
...since you are not connecting to any mongo server

Related

Yii2: rest api model get data

I am using REST API in my project and everything works great. I describe a model using a model
<?php
namespace api\modules\v1\models;
use Carbon\Carbon;
use Yii;
class Comment extends \common\models\Comment
{
public function fields()
{
return [
'id',
'user' => function(Comment $model) {
return User::findOne($model->user_id);
},
'text',
'image' => function(Comment $model) {
return Yii::$app->params['link'].$model->image;
},
'created_at' => function(Comment $model) {
Carbon::setLocale(Yii::$app->language);
return Carbon::createFromTimeStamp(strtotime($model->created_at))->diffForHumans();
},
'children' => function(Comment $model) {
$comments = Comment::find()
->where(['comment_id' => $model->id]);
if (!$comments->exists()) {
return false;
}
return $comments->all();
},
'like',
'news_id',
'comment_id'
];
}
}
The data is returned in the specified format and that's great. But I need to send data to the controller using websockets. For example, when a new comment arrives, send it to all users.
$post = Yii::$app->request->post();
$image = UploadedFile::getInstanceByName('image');
$model = new \api\modules\v1\models\Comment([
'news_id' => $post['feed_id'],
'comment_id' => $post['comment_id'] ?? null,
'user_id' => Yii::$app->user->identity->id,
]);
$model->text = $model->findLinks($post['text']);
if ($image && !$image->error) {
if (!file_exists(Yii::$app->params['comment.pathAbsolute'])) {
if (!FileHelper::createDirectory(Yii::$app->params['comment.pathAbsolute'], 0777)) {
throw new \Exception('Помилка створення папки');
}
}
$serverName = Yii::$app->security->generateRandomString(16).'.'.$image->extension;
if ($image->saveAs(Yii::$app->params['comment.pathAbsolute'].$serverName)) {
$model->image = $serverName;
} else {
throw new \Exception($image->error);
}
}
if (!$model->save()) {
throw new \Exception($model->error());
}
Helper::ws(false, 'updateComment', ['feed_id' => $post['feed_id'], 'comment' => $model]);
And when I pass the $model, the data is passed as it is stored in the database. Is it possible to call a method or something so that the data is passed as I described in the model api?

yii2 image is uploaded but not saved in db

I want to save my image in db it is uploaded but not saved in my database any one know how to fix this
public function actionUpdate($id) {
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post())) {
$fname = UploadedFile::getInstance($model, 'imageFile');
if (!empty($fname)) {
$temp_path = Yii::$app->basePath . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR;
$model->save();
$fname->saveAs($temp_path . $fname);
$model->imageFile = $fname->name;
// echo '<pre>'; print_r($fname->name);
//exit();
}
if ($model->save()) { // To save the title to the database
Yii::$app->getSession()->addFlash('success', 'Image uploaded');
return $this->redirect(['index']);
}
} else {
return $this->render('update', [
'model' => $model,
]);
}
}

Error with session ini setting modification

A PHP Error was encountered
Severity: Warning
Message: ini_set(): A session is active. You cannot change the session module's ini settings at this time
Filename: Session/Session.php
Line Number: 316
Backtrace:
File: C:\xampp\htdocs\testing\index.php
Line: 315
Function: require_once
<?php
session_start(); //we need to start session in order to access it through CI
class Adminlogin extends CI_Controller {
public function _construct(){
parent::_construct();
//Load form helper library
$this->load->helper('form');
//Load form validation library
$this->load->library('form_validation');
//Load session library
$this->load->library('session');
//Load database
$this->load->model('login_database');
}
//show login page
public function index()
{
$this->load->view('admin_login');
}
//show registration page
public function user_registration_show(){
$this->load->view('admin_signup');
}
//Validate and store registration data in database
public function new_user_registration(){
//Check Validation for user input in SignUp form
$this->form_validation->set_rules('admin_username', 'Username','trim|required|xss_clean');
$this->form_validation->set_rules('admin_password', 'Password','trim|required|xss_clean');
if($this->form_validation->run()== FALSE){
$this->load->view('admin_signup');}
else{
$data = array(
'admin_username' => $this->input->post('username'),
'admin_password' => $this->input->post('password'));
$result = $this->login_database->registration_insert($data);
if($result == TRUE){
$data['message_display'] = 'Registration Successfully !';
$this->load->view('admin_login', $data);
}else{
$data['message_display'] = 'Username already exist';
$this->load->view('admin_signup',$data);
}
}
}
//Check for user login process
public function user_login_process(){
$this->form_validation->set_rules('admin_username','Username', 'trim|required|xss_clean');
$this->form_validation->set_rules('admin_password','Password', 'trim|required|xss_clean');
if($this->form_validation->run() == FALSE){
if(isset($this->session->userdata['loggen_in'])){
$this->load->view('Admin/admin_dashboard');
}else{
$this->load->view('admin_login');
}
}else{
$data = array(
'admin_username' => $this->input->post('username'),
'admin_password' => $this->input->post('password'));
$result = $this->login_database->login($data);
if($result == TRUE) {
$username = $this->input->post('username');
$result = $this->login_database->read_user_information($username);
if($result != false){
$session_data = array(
'username' => $result[0]->admin_username,
'password' => $result[0]->admin_password);
//Add user data in session
$this->session->set_userdata('logged_in', $session_data);
$this->load->view('Admin/admin_dashboard');
}else{
$data = array(
'error_message' => 'Invalid Username or Password');
$this->load->view('admin_login',$data);
}
}
}
}
}
?>
Please remove the 1st line session_start(); or change it to..
// session_start(); //I do Not need this as I am using CI Sessions.
You are using CodeIgniters Sessions which you have loaded in your code...
$this->load->library('session');
As an Aside:
You don't need the end ?> in your PHP files where it is the last tag in the file.

Slim 3 - How to add 404 Template?

In Slim 2, I can over write the default 404 page easily,
// #ref: http://help.slimframework.com/discussions/problems/4400-templatespath-doesnt-change
$app->notFound(function () use ($app) {
$view = $app->view();
$view->setTemplatesDirectory('./public/template/');
$app->render('404.html');
});
But in Slim 3,
// ref: http://www.slimframework.com/docs/handlers/not-found.html
//Override the default Not Found Handler
$container['notFoundHandler'] = function ($c) {
return function ($request, $response) use ($c) {
return $c['response']
->withStatus(404)
->withHeader('Content-Type', 'text/html')
->write('Page not found');
};
};
How can I add my 404 template ('404.html') in?
Create your container:
// Create container
$container = new \Slim\Container;
// Register component on container
$container['view'] = function ($c) {
$view = new \Slim\Views\Twig('./public/template/');
$view->addExtension(new \Slim\Views\TwigExtension(
$c['router'],
$c['request']->getUri()
));
return $view;
};
//Override the default Not Found Handler
$container['notFoundHandler'] = function ($c) {
return function ($request, $response) use ($c) {
return $c['view']->render($response->withStatus(404), '404.html', [
"myMagic" => "Let's roll"
]);
};
};
Construct the \Slim\App object using the $container and run:
$app = new \Slim\App($container);
$app->run();
Option 1:
use Twig (or any other templating engine)
Option 2:
$notFoundPage = file_get_contents($path_to_404_html);
$response->write($notFoundPage);

Change dynamically validated_file_class in symfony 1.4

I have this model:
Banner:
columns:
filename: string(255)
url: string(255)
position:
type: enum
values: [top, right]
default: right
and this form:
class BannerForm extends BaseBannerForm
{
public function configure()
{
$this->widgetSchema['filename'] = new sfWidgetFormInputFileEditable(array(
'file_src' => $this->getObject()->getThumbURL(),
'is_image' => true,
'edit_mode' => $this->getObject()->exists()
));
$validated_file_class = $this->getObject()->position === 'right' ? 'bannerRightValidatedFile' : 'bannerTopValidatedFile';
$this->validatorSchema['filename'] = new sfValidatorFile(array(
'path' => sfConfig::get('sf_upload_dir'),
'mime_types' => 'web_images',
'validated_file_class' => $validated_file_class',
'required' => $this->getObject()->isNew()
));
}
}
I use different validate classes because inside it i incapsulate thumbnail operations, and the sizes of banners depends on it position field.
The problem is that $validated_file_class is always bannerRightValidatedFile class.
How i can achieve this thing ?
I can suggest 4 solutions which you can choose from:
Option 1:
You should add a update$fieldNameColumn method to the form class. In your case it should look like this:
// change validated file instance before calling save
protected function updateFilenameColumn($value)
{
if ($value instanceof sfValidatedFile)
{
$class = 'right' == $this->getValue('position') ? 'bannerRightValidatedFile' : 'bannerTopValidatedFile';
// this will not work as I thought at first time
// $this->getValidator('filename')->setOption('validated_file_class', $class);
$this->values['filename'] = new $class(
$value->getOriginalName(),
$value->getType(),
$value->getTempName(),
$value->getSize(),
$value->getPath()
);
return $this->processUploadedFile('filename');
}
return $value;
}
I think it's kind of hacky.
Option 2:
You should add a doctrine hook method to the model:
/**
* #param Doctrine_Event $event
*/
public function postSave($event)
{
$record = $event->getInvoker();
if (array_key_exists('filename', $record->getLastModified()))
{
// get the full path to the file
$file = sfConfig::get('sf_upload_dir') . '/' . $record->getFilename();
if (file_exists($file))
{
// resize the file e.g. with sfImageTransformPlugin
$img = new sfImage($file);
$img
->resize(100, 100)
->save();
}
}
}
This will work when creating records whitout a form e.g. when using fixtures.
Option 3:
Use the admin.save_object event.
public static function listenToAdminSaveObject(sfEvent $event)
{
$record = $event['object'];
if ($event['object'] instanceof Banner)
{
// use the same code as in the `postSave` example
}
}
Option 4:
Use the sfImageTransformExtraPlugin
It's kind of hard to setup and configure (and it's code is a mess :), but it makes possible to modify the size of the image whithout regenerating all the already resized ones.
You could add a sfCallbackValidator as a post-validator, and set the property accordingly.
Pseudo code (I don't have the exact function signatures at hand).
public function configure() {
// ...
$this->mergePostValidator(new sfCallbackValidator(array('callback' => array($this, 'validateFile'))));
}
public function validateFile($values) {
$realValidator = new sfValidatorFile(...);
return $realValidator->clean($values['field']);
}
If you can modify the call to the form class, you can do that:
$form = new BannerForm(array(), array('validated_file_class' => 'bannerRightValidatedFile');
$form2 = new BannerForm(array(), array('validated_file_class' => 'bannerTopValidatedFile');
And then in your form:
class BannerForm extends BaseBannerForm
{
public function configure()
{
$this->widgetSchema['filename'] = new sfWidgetFormInputFileEditable(array(
'file_src' => $this->getObject()->getThumbURL(),
'is_image' => true,
'edit_mode' => $this->getObject()->exists()
));
$this->validatorSchema['filename'] = new sfValidatorFile(array(
'path' => sfConfig::get('sf_upload_dir'),
'mime_types' => 'web_images',
'validated_file_class' => $this->options['validated_file_class'],
'required' => $this->getObject()->isNew()
));
}
}
Edit:
Since you are playing inside the admin gen, I think the best way is to use a postValidator like #Grad van Horck says.
Your validate class depend on an extra field. With a postvalidator, you can access any field inside the form. Then, you just need to create a little switch to handle the case for each position / validated class.
public function configure()
{
// ...
$this->mergePostValidator(new sfValidatorCallback(array('callback' => array($this, 'validateFile'))));
}
public function validateFile($validator, $values, $arguments)
{
$default = array(
'path' => sfConfig::get('sf_upload_dir'),
'mime_types' => 'web_images',
'required' => $this->getObject()->isNew()
);
switch ($values['position'] ) {
case 'right':
$validator = new sfValidatorFile($default + array(
'validated_file_class' => 'bannerRightValidatedFile',
));
break;
case 'top':
$validator = new sfValidatorFile($default + array(
'validated_file_class' => 'bannerTopValidatedFile',
));
default:
# code...
break;
}
$values['filename'] = $validator->clean($values['filename']);
return $values;
}