Sending SMS in yii2 - php

I'm using two models in one controller. one of them is database model (model) another model is for sending sms (smsModel).
I have problem in smsModel.
I got this error in my result:
Class 'fcadmin\models\SoapClient' not found
How can I fix it?
My controller:
public function actionCreate($id) {
$model = new Requestresult();
$smsModel = new SmsSender();
$request_model = Request::findOne(['id' => $id]);
$model->CodeKargah = $request_model->CodeKargah;
$model->month = $request_model->month;
$model->trackingCode = $request_model->trackingCode;
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$smsModel->sendSms('09193452126', 'sdf');
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
smsModel:
public function sendSms($to, $text) {
$options = [
'login' => 'myusername',
'password' => 'mypassword'
];
$client = new SoapClient('http://sms.hostiran.net/webservice/?WSDL', $options);
$messageId = $client->send($to, $text);
sleep(3);
return ($client->deliveryStatus($messageId));
}

You need to read up about namespaces. If you're in a namespace and don't tell PHP that you want to use the global namespace, it will look for classes of name x in the current namespace.
In your case you need to be using new \SoapClient.

Related

When i refresh page, my application continue inserting data into database Yii2

Theres the action
public function actionEfetuarPedidoReserva($idQuarto){
$modelPedidoReservaQuarto = new PedidoReservaQuarto();
$modelPedidoReserva = new PedidoReserva();
$model = new ComodidadesExtra();
$modelListaComodidades = new ListaComodidadesQuarto();
$modelPedidoReservaQuarto->quartoId = $idQuarto;
if($modelPedidoReservaQuarto->save()){
$modelPedidoReserva->nPessoas = 2;
$modelPedidoReserva->preco = 70.00;
$modelPedidoReserva->reservaQuartoId = $modelPedidoReservaQuarto->id;
$modelPedidoReserva->userInfoId = Yii::$app->user->id;
if($modelPedidoReserva->save()){
$model->pedidoReservaId = $modelPedidoReserva->id;
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['efetuar-pedido-reserva', 'idQuarto' => $idQuarto]);
}
return $this->render('../comodidades-extra/create', [
'model' => $model, 'modelLista' => $modelListaComodidades
]);
}
}
}
When i refresh page, it add the last pedidoreservaid inserted + 1;
i Would like to know if am i doing it the right way.
Your problem is that you create new instance of ComodidadesExtra each time when you call $model = new ComodidadesExtra();. Yii2 consider it as new independent row and you need to tell Yii2 that you should take existing row instead, using:
$model = ComodidadesExtra::find()
->where(['pedidoReservaId' => $modelPedidoReserva->id])
->one();
And your controller should look like:
if($modelPedidoReserva->save()){
if(null===($model = ComodidadesExtra::find()->where(['pedidoReservaId' => $modelPedidoReserva->id])
->one())) {
$model = new ComodidadesExtra();
}
$model->pedidoReservaId = $modelPedidoReserva->id;
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['efetuar-pedido-reserva', 'idQuarto' => $idQuarto]);
}
return $this->render('../comodidades-extra/create', [
'model' => $model, 'modelLista' => $modelListaComodidades
]);
}

yii2 ajax validation error in widget, yii\web\Response

I'm getting error from yii\web\Response when I use ajax validation.
Object of class yii\web\Response could not be converted to string
widget:
public function run()
{
$model = new Participants();
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
if ($model->load(Yii::$app->request->post())) {
$list = implode( ", ",$model->sections);
$model->sections = $list;
$model->save();
Yii::$app->session->setFlash(Alert::TYPE_SUCCESS, [
[
'title' => 'Congratulations!',
'text' => 'You are registered on the forum. Check out your email to get news about forum.',
'confirmButtonText' => 'Done!',
]
]);
return Yii::$app->controller->redirect(Yii::$app->request->referrer ?: Yii::$app->homeUrl);
}
return $this->render('header', [
'model' => $model,
]);
}
view of widget:
<?php $form = ActiveForm::begin();?>
...
<?= $form->field($model, 'email', ['enableAjaxValidation' => true])->textInput(['placeholder' => 'Email']); ?>
how I can solve this error? P.S. yii version - 2.0.17-dev
\yii\base\Widget::run() must return a string (all widgets basically)
All you should do within method run() is output or render content and you're attempting to return a Response object by way of return ActiveForm::validate($model); and return Yii::$app->controller->redirect(..)
i suggest you move all the code that supposed to handle form submission to it's own action
SiteController extends controller {
public function actionRegisterParticipant {
$model = new Participants();
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
if ($model->load(Yii::$app->request->post())) {
$list = implode(", ", $model->sections);
$model->sections = $list;
$model->save();
Yii::$app->session->setFlash(Alert::TYPE_SUCCESS, [
[
'title' => 'Congratulations!',
'text' => 'You are registered on the forum. Check out your email to get news about forum.',
'confirmButtonText' => 'Done!',
]
]);
return Yii::$app->controller->redirect(Yii::$app->request->referrer ?: Yii::$app->homeUrl);
}
// ...
}
and the form in the widget view should always point to this action:
<?php $form = ActiveForm::begin(['action' => 'site/register-participant']);?>
...
<?= $form->field($model, 'email', ['enableAjaxValidation' => true])->textInput(['placeholder' => 'Email']); ?>
Widget should return string as a result, but return Yii::$app->controller->redirect() returns Response object with configured redirection. If you want to redirect inside of widget you should use something like that:
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->controller->asJson(ActiveForm::validate($model));
Yii::$app->end();
}
// ...
Yii::$app->session->setFlash(/* ... */);
Yii::$app->controller->redirect(Yii::$app->request->referrer ?: Yii::$app->homeUrl);
Yii::$app->end();
But this smells like a bad design - widget should not be responsible for controlling application flow. It is better to handle user input in regular action/controller.

Laravel 5.6, where to keep additional classes (additional functional)?

I need to make request on some CRM api in my controller. For making this I have pretty big method. It's look like ugly. I know that there are some "Services" and to put additional code into Service is a good way. But I don't know what is this. Is it a custom classes into app folder? Or maybe it's Service-providers? I have read service-providers documentation and I'm not sure that service-providers is suitable for this. Here is my code:
<?php
namespace App\Http\Controllers;
use App\User;
use App\UserInfo;
use Validator;
use Illuminate\Http\Request;
class UserController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$users = User::with('info')
->paginate(20);
$users->withPath(DIRECTORY_SEPARATOR . $request->path() .DIRECTORY_SEPARATOR);
return response()->json($users)->setEncodingOptions(JSON_UNESCAPED_UNICODE);
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$data = $request->json()->all();
$rules = [
'name' => 'required',
'phone' => 'required|unique:users'
];
$validator = Validator::make($data, $rules);
if ($validator->fails()) return response()->json(['errors'=>$validator->errors()]);
$user = new User();
$user->name = request('name');
$user->phone = request('phone');
$user_info_obj = $this->storeUserInfo();
if($user_info_obj === null){
return response('Impassible to define user geo data', 400);
}
$user->info_id = $user_info_obj->id;
$user->save();
$this->makeAMOLead($user->name,
$user->phone,
$user_info_obj->user_agent,
$user_info_obj->city,
$user_info_obj->country);
return response()->json(['success' => 'User created successfully']);
}
public function storeUserInfo()
{
$ip = request()->ip();
$reader = new \GeoIp2\Database\Reader('../resources/geo-lite2-city_20180807/GeoLite2-City.mmdb');
try {
$record = $reader->city($ip);
}
catch (\Throwable $e){
// Code bellow is for testing on localhost, Because of maybe exception instead of geo obj on localhost.
$info = new UserInfo();
$info->ip = '127.0.0.1';
$info->city = 'Some city';
$info->country = 'Some country';
$info->country_code = 'Some code';
$info->continent = 'Some continent';
$info->continent_code = 'no';
$info->user_agent = 'User agent';
$info->save();
return $info;
//return null;
}
$city = $record->city->names['ru'];
$continent = $record->continent->names['ru'];
$continent_code = $record->continent->code;
$country = $record->country->names['ru'];
$country_code = $record->country->isoCode;
$user_agent = \request()->userAgent();
$info = new UserInfo();
$info->ip = $ip;
$info->city = $city;
$info->country = $country;
$info->country_code = $country_code;
$info->continent = $continent;
$info->continent_code = $continent_code;
$info->user_agent = $user_agent;
$info->save();
return $info;
}
private function makeAMOLead($name, $phone, $userAgent, $city, $country)
{
$domain = env('AMO_DOMAIN');
$login = env('AMO_LOGIN');
$hash = env('AMO_HASH');
try {
$credentials = new \ddlzz\AmoAPI\CredentialsManager($domain, $login, $hash);
$settings = new \ddlzz\AmoAPI\SettingsStorage();
$settings->setCookiePath(env('AMO_COOKIE_FILE_PATH'));
$request = \ddlzz\AmoAPI\ClientFactory::create($credentials, $settings);
$lead = new \ddlzz\AmoAPI\Model\Amo\Lead();
$lead['name'] = $name;
if(env('AMO_PIPELINE_ID', null)){
$lead['pipeline_id'] = intval(env('AMO_PIPELINE_ID'));
}
$lead['name'] = 'New pickup user ' . $name;
$lead['custom_fields'] = [
[
'id' => env('AMO_NAME_FIELD_ID'),
'values' => [
['value' => $name],
]
],
[
'id' => env('AMO_USER_AGENT_FIELD_ID'),
'values' => [
['value' => $userAgent]
]
],
[
'id' => env('AMO_CITY_FIELD_ID'),
'values' => [
['value' => $city]
]
],
[
'id' => env('AMO_COUNTRY_FIELD_ID'),
'values' => [
['value' => $country]
]
],
];
$lead['created_at'] = time();
$result = $request->add($lead);
$pipelineId = json_decode($result)->_embedded->items{0}->id;
// create contact
$contact = new \ddlzz\AmoAPI\Model\Amo\Contact();
$contact['name'] = $name;
$contact['created_at'] = time();
$contact['leads_id'] = "$pipelineId";
// dd($request->accountInfo(), true); // Call this, if you need to know ids of default fields (like phone, or position)
$contact['custom_fields'] = [
[
'id' => env('AMO_CONTACT_PHONE_ID'),
'values' => [
[
'value' => $phone,
'enum' => 'MOB',
],
]
],
];
$result = $request->add($contact);
} catch (Exception $e) {
echo response()->json(['error' => $e->getFile() . ': ' . $e->getMessage()]);
}
}
}
Look on the makeAMOLead. This is big method in my controller and this is not ok for controller conception.
Please use repository pattern to split all the communication between the application and your data source. and call the repository functions inside your controller. It is good practice. Here is an article you can understand about that
Example:
Your functions can be separate from controller to repository.
storeUserInfo
makeAMOLeadin
Move your functions an repository and call them into your controller.

Validating content before save in yii2

I am using yii2 for a weigh bridge project
Upon create, the user is redirected to view but my controller doesn't validate the information in such a way that even if data is not entered in the form fields a user is always redirected to view.
How can I implement the validation property
Controller code:
public function actionCreate()
{
$model = new TruckWeight1();
if ($model->load(Yii::$app->request->post()) ) {
$model->time_recorded =date('H:i:s');;
$model->recorded_by =
$model->recorded_date = date('Y-m-d');
$model->save();
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
try this
public function actionCreate()
{
$model = new TruckWeight1();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$model->time_recorded =date('H:i:s');;
$model->recorded_by =
$model->recorded_date = date('Y-m-d');
$model->save();
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
for more on validation validation

Laravel 4 Validation

I use the following rules for validation on creating a new user:
protected $rules= [
'name' => 'required',
'email' => [
'required',
'unique:user',
'email'
]
];
When updating an existing user I use the same ruleset as shown above
but don't want a validation error if the user didn't change his email at all.
I currently resolve this by using the following:
if (!User::changed('email')) {
unset($user->email);
}
It feels like a dirty workaround to me so I was wondering if there are better alternatives.
Also note that the changed method is something I wrote myself. Does anyone know if there
is a native Laravel 4 method for checking whether a model property has changed?
Thanks!
The unique validation rule allows to ignore a given ID, which in your case is the ID of the data set you are updating.
'email' => 'unique:users,email_address,10'
http://four.laravel.com/docs/validation#rule-unique
One approach is to create a validation function in the model and call it with the controller passing in the input, scenario and id (to ignore).
public function validate($input, $scenario, $id = null)
{
$rules = [];
switch($scenario)
{
case 'store':
$rules = [
'name' => 'required|min:5|unique:users',
'email' => 'required|email|unique:users',
'password' => 'required|min:4|confirmed'
];
break;
case 'update';
$rules = [
'name' => 'required|min:5|unique:users' .',name,' . $id,
'email' => 'required|email|unique:users' .',email,' . $id,
'password' => 'min:4|confirmed'
];
break;
}
return Validator::make($input, $rules);
}
Then in the controller:
$input = Input::all();
$validation = $user->validate($input, 'update', $user->id);
if ($validation->fails())
{
// Do stuff
}
else
{
// Validation passes
// Do other stuff
}
As others mentioned, the 3rd parameter of the unique rule specifies an id to ignore. You can add other cases, such as 'login' to reuse the validation function.
Alternatively, Jeffrey Way at Tuts Premium has a great series of lessons in "What's New In Laravel 4" which includes a couple of other approaches to handling validation using services and listeners.
See the documentation on http://four.laravel.com/docs/validation#rule-unique
You can exclude the users own id
protected $rules= [
'name' => 'required',
'email' => [
'required',
'unique:user,email,THE_USERS_USER_ID',
'email'
]
];
As of 2014-01-14, you can use sometimes attribute, I believe Taylor added them 2 days ago to Laravel 4.1
$v = Validator::make($data, array(
'email' => 'sometimes|required|email',
));
sometimes only validate input if it exists. this may or may not suit your exact scenario, if you don't have a default value for insert.
http://laravel.com/docs/validation#conditionally-adding-rules
I handle this sort of thing in my validator function. My validators array is setup as a class variable. I then do something like this:
public function validate()
{
//exclude the current user id from 'unqiue' validators
if( $this->id > 0 )
{
$usernameUnique = 'unique:users,username,'.$this->id;
$emailUnique = 'unique:users,email,'.$this->id;
$apiUnique = 'unique:users,api_key,'.$this->id;
}
else
{
$usernameUnique = 'unique:users,username';
$emailUnique = 'unique:users,email';
$apiUnique = 'unique:users,api_key';
}
$this->validators['username'] = array('required', 'max:32', $usernameUnique);
$this->validators['email'] = array('required', 'max:32', $emailUnique);
$this->validators['api_key'] = array('required', 'max:32', $apiUnique);
$val = Validator::make($this->attributes, $this->validators);
if ($val->fails())
{
throw new ValidationException($val);
}
}
I have solved this by having different rules for update and create on models that need to do so, like Users.
I have a Model class that extends Eloquent, where I define the validation, and then all child models that extend the Model can have have both the $rules and $update_rules defined. If you define only $rules, it will be used both for create and update.
class Model extends Eloquent {
protected $errors;
protected static $rules = array();
protected $validator;
public function __construct(array $attributes = array(), Validator $validator = null) {
parent::__construct($attributes);
$this->validator = $validator ?: \App::make('validator');
}
protected static function boot() {
parent::boot();
# call validatie when createing
static::creating(function($model) {
return $model->validate();
});
# call validatie when updating with $is_update = true param
static::updating(function($model) {
return $model->validate(true);
});
}
public function validate($is_update = false) {
# if we have $update_rules defined in the child model, and save is an update
if ($is_update and isset(static::$update_rules)) {
$v = $this->validator->make($this->attributes, static::$update_rules);
}
else {
$v = $this->validator->make($this->attributes, static::$rules);
}
if ($v->passes()) {
return true;
}
$this->setErrors($v->messages());
return false;
}
protected function setErrors($errors) {
$this->errors = $errors;
}
public function getErrors() {
return $this->errors;
}
public function hasErrors() {
return ! empty($this->errors);
}
}

Categories