Updrading Stripe Payment method To V3 version - axios

Hi guys I have created a stipe payment method a it works fine but I want to upgrade to the stripe v3 but I don't how tp convert my old method to the new one I look at the doc be they are not so clear here is my old code
I am using Altorouter and illuminate for database and blade template engine Vue for front end and axious for HTTP
My route
$router->map('POST', '/cart/payment', 'App\Controllers\CartController#Payment', 'Payment');
my cart.blade.php file
<button #click.prevent='checkout' class="btn btn-outline-success">Checkout - <i class="fa fa-credit-card"
aria-hidden="true"></i></button>
<span id="proporities" class="hide" data-customer-email='{{ user()->email
data-stripe-api='{{ \App\Classes\Session::get('stripe_key') }}'>
</span>
after this button get click I take the information to cart.js here is the cart.js code
var stripe = StripeCheckout.configure({
key: $('#proporities').data('stripe-api'),
locale: 'auto',
token: function(token) {
var data = $.param({
stripeToken: token.id,
stripeEmail: token.email
});
axios.post('/cart/payment', data).then(function(response) {
$('.notifty').css('display', 'block').delay(2000).slideUp(300).html(response.data.success);
app.showcart(10);
}).catch(function(error) {
console.log(error)
});
}
});
var app = new Vue({
el: '#cart',
data: {
amount: 0
},
methods: {
checkout: function() {
stripe.open({
name: 'Cartzilla Store Inc.',
description: 'Your Shopping Cart',
zipCode: true,
amount: app.amount,
email: $('#proporities').data('customer-email')
});
}
in the cart.js axious take to information to PHP controller which I have defined in the top route
here is the controller code
public function payment()
{
$array = [];
if (Request::has('post')) {
$request = Request::get('post');
$email = $request->stripeEmail;
$token = $request->stripeToken;
try {
$customer = Customer::create([
'email' => $email,
'source' => $token
]);
$amount = convertMoney(Session::get('carttotal'));
$charge = Charge::create([
'customer' => $customer->id,
'amount' => $amount,
'description' => user()->fullname . 'Cart Purchase',
'currency' => 'usd'
]);
$orderId = strtoupper(uniqid());
foreach ($_SESSION['user_cart'] as $items) {
$productId = $items['product_id'];
$quantity = $items['quantity'];
$product = Product::where('id', $productId)->first();
if (!$product) {
continue;
}
$totalPrice = $product->price * $quantity;
$totalPrice = number_format($totalPrice, 2);
Order::create([
'user_id' => user()->id,
'product_id' => $productId,
'unit_price' => $product->price,
'status' => 'pending',
'total_price' => $amount,
'order_no' => $orderId,
'quantity' => $quantity
]);
$product->quantity = $product->quantity - $quantity;
$product->save();
array_push($array, [
'name' => $product->name,
'price' => $product->price,
'quantity' => $quantity,
'total' => $totalPrice,
]);
Payment::create([
'user_id' => user()->id,
'amount' => $charge->amount,
'status' => $charge->status,
'order_no' => $orderId
]);
}
Session::remove('user_cart');
echo json_encode(['success' => 'Thank You we Have Recevied Your Payment And Now Processing Your Order']);
} catch (\Throwable $th) {
//throw $th;
}
}
}
apart from this, I have to model to for order table and payment table
and here are the model
Order.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Order extends Model
{
use SoftDeletes;
public $timestamp = true;
public $fillable = ['user_id', 'product_id', 'unit_price', 'qunatity', 'total_price', 'status', 'order_no'];
public $date = ['deleted_at'];
}
and Payment .php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Payment extends Model
{
use SoftDeletes;
public $timestamp = true;
public $fillable = ['user_id', 'amount', 'status', 'order_no'];
public $date = ['deleted_at'];
}

Related

CodeIgniter 4: Call to member function on null where post request is valid in var_dump()

** Very new to CodeIgniter so please be kind! **
I have an issue with my two user authentication forms: users/register.php and users/login.php where I cannot pass the post input to functions in my model.
As of now, I'm getting the error Call to member function addUser() on null on the registration form and a validation error on the login form that states the username/password don't match any credentials in the database. Both seem to stem from post being null although it is not.
I have done a var_dump on $login which is defined as $login = $this->request->getPost() as well as inspected the request in Firefox Developers Browser to find all the post data correctly displayed. I am stumped. Why can't I pass this array to my model?
Here is a screenshot of the post request for login.php (the same can be said for registration.php and is not included).
These are my routes:
// Login and Registration
$routes->match(['get', 'post'], 'users/register', 'Users::register');
$routes->match(['get', 'post'], 'users/login', 'Users::login', ["filter" => "noauth"]);
Here is my model UserModel.php in its entirety:
class UserModel extends Model
{
protected $DBGroup = 'default';
protected $table = 'users';
protected $primaryKey = 'username';
protected $useAutoIncrement = false;
protected $insertID = 0;
protected $returnType = 'object';
protected $useSoftDelete = false;
protected $allowedFields = [
'username',
'password',
'id',
'role',
'profile_image',
'profile_views',
'last_login',
'about_me',
'age',
'gender',
'occupation',
'hometown',
'country',
'fav_shape',
'fav_color',
'created',
'modified',
];
// Dates
protected $useTimestamps = true;
protected $dateFormat = 'datetime';
protected $createdField = 'created';
protected $modifiedField = 'modified';
// Callbacks
protected $allowCallbacks = true;
protected $beforeInsert = ['beforeInsert'];
public function __construct()
{
parent::__construct();
}
protected function beforeInsert(array $data)
{
$data = $this->passwordHash($data);
return $data;
}
protected function passwordHash(array $data)
{
if (isset($data['password'])) {
$data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
}
return $data;
}
public function lastLogin($username)
{
$this->builder()
->where('username', $username)
->update('last_login', date('Y-m-d H:i:s'));
}
public function addUser($newUser)
{
$builder = $this->builder()
->set($newUser)
->insert();
if ($builder->affected_rows() == 1) {
return TRUE;
} else {
return FALSE;
}
}
public function getUser($username)
{
$builder = $this->builder()
->where(['username' => $username])
->limit(1);
if ($builder->countAllResults() === 1) {
return $builder->get()->getRow();
} else {
return FALSE;
}
}
}
Here are excerpts from my controller Users.php:
class Users extends BaseController
{
protected $userModel;
public function __construct()
{
$userModel = new UserModel();
}
public function login()
{
$validation = \Config\Services::validation();
// Set session variable
$session = session();
if ($this->request->getMethod() === 'post' && ! empty($_POST)) {
$validation->getRuleGroup('login');
$validation->setRuleGroup('login');
$validation->withRequest($this->request)->run();
$recaptchaResponse = trim($this->request->getVar('g-recaptcha-response'));
$userIp = $this->request->getIPAddress();
$secret = env('recaptcha2_secretkey');
$credential = [
'secret' => $secret,
'response' => $recaptchaResponse,
'remoteip' => $userIp,
];
$verify = curl_init();
curl_setopt($verify, CURLOPT_URL, 'https://www.google.com/recaptcha/api/siteverify');
curl_setopt($verify, CURLOPT_POST, TRUE);
curl_setopt($verify, CURLOPT_POSTFIELDS, http_build_query($credential));
curl_setopt($verify, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($verify, CURLOPT_RETURNTRANSFER, TRUE);
$response = curl_exec($verify);
$status = json_decode($response, TRUE);
curl_close($verify);
if (empty($validation->getErrors()) && $status['success']) {
$login = $this->request->getPost();
$user = $this->userModel->getUser($login['username']);
// Storing session values
$this->setUserSession($user);
// Storing success message
$session->setFlashdata('success', 'You have successfully logged in!');
// Update last login datetime
$this->userModel->lastLogin($login['username']);
// Redirecting to dashboard after login
if ($user['role'] == 1) {
return redirect()->to('admin/dashboard');
} elseif ($user['role'] == 0) {
return redirect()->to('members/dashboard');
}
} else {
$data = [
'title' => 'Login',
'errors' => $validation->getErrors(),
];
echo view('templates/index_header', $data);
echo view('users/login');
echo view('templates/footer', $data);
}
} else {
$data = [
'title' => 'Login',
];
echo view('templates/index_header', $data);
echo view('users/login');
echo view('templates/footer', $data);
}
}
/**
* Sets session with user id, username, isLoggedIn, and role for use in member/admin site
* #param model user data
* #return boole if session was set successfully
*/
private function setUserSession($user)
{
$data = [
'id' => $user->id,
'username' => $user->username,
'profile_image' => $user->profile_image,
'isLoggedIn' => true,
'role' => $user->role,
];
if (session()->set($data)) {
return true;
} else {
return false;
}
}
public function register()
{
$validation = \Config\Services::validation();
if ($this->request->getMethod() == 'post' && ! empty($_POST)) {
$validation->getRuleGroup('registration');
$validation->setRuleGroup('registration');
$validation->withRequest($this->request)->run();
if (empty($validation->getErrors())) {
$newUser = $this->request->getPost();
if ($this->userModel->addUser($newUser)) {
$this->session->setFlashdata('success', 'Successful Registration');
$data['title'] = 'Login';
echo view('templates/index_header', $data);
echo view('users/login');
echo view('templates/footer', $data);
} else {
$this->session->setFlashdata('error', 'Something went wrong with your registration! Please try again.');
}
} else {
$data = [];
$data = [
'title' => 'Register',
'script' => 'js/click_link',
'errors' => $validation->getErrors(),
];
echo view('templates/index_header', $data);
echo view('users/register', $data);
echo view('templates/footer', $data);
}
} else {
$data = [
'title' => 'Register',
'script' => 'js/click_link',
];
echo view('templates/index_header', $data);
echo view('users/register', $data);
echo view('templates/footer', $data);
}
}
}
These are my validation rules in Config\Validation:
/**
* Registration
*/
public $registration = [
'username' => 'required|is_unique[users.username,username]|min_length[5]|max_length[25]|alpha_dash|badWordsFilter[username]',
'password' => 'required|min_length[8]|max_length[255]|regex_match[/^(?=.*[!##$%^&*-])(?=.*[0-9])(?=.*[A-Z]).{8,255}$/]',
'pass_confirm' => 'required|matches[password]',
'about_me' => 'permit_empty|max_length[250]|alpha_numeric_punct|badWordsFilter[about_me]',
'occupation' => 'permit_empty|max_length[50]|alpha_space|badWordsFilter[occupation]',
'hometown' => 'permit_empty|max_length[50]|alpha_space|badWordsFilter[hometown]',
'age' => 'permit_empty|less_than[100]|greater_than[0]|numeric',
'country' => 'permit_empty',
];
/**
* Password Verification
*/
public $login = [
'password' => 'required|validateUser[username,password]',
];
This is my custom rule to authenticate username and password credentials User_rules:
class User_rules
{
/**
* Checks if input username exists in database and then checks whether the input password matches the hash for that username
* #param string $str is the input password
* #param string $fields are the associated form fields that are being used
* #param array $data is an array containing the values for the fields indexed by field names
* #return boolean true or false depending on if the user exists and the password matches the hashed password stored in the database
*/
public function validateUser(string $str, string $fields, array $data)
{
$userModel = new UserModel();
$user = $userModel->getUser($data['username']);
if(!$user) {
return FALSE;
}
return password_verify($data['password'], $user->password);
}
Lastly, my view for login.php:
<div class='form-container'>
<?= form_open('users/login',['autocomplete' => FALSE]); ?>
<div class='form-header'>
<h2>Login</h2>
</div>
<div class='form-body'>
<div class='form-row'>
<div class='input-container'>
<i class='fas fa-user'></i>
<?php $attributes = [
'type' => 'text',
'name' => 'username',
'class' => 'input-field',
'id' => 'username',
'placeholder' => 'Username',
'required' => TRUE,
]; ?>
<?= form_input($attributes); ?>
</div>
</div>
<div class='form-row'>
<div class='input-container'>
<i class='fas fa-lock'></i>
<?php $attributes = [
'type' => 'password',
'name' => 'password',
'class' => 'input-field',
'placeholder' => 'Password',
'required' => TRUE,
]; ?>
<?= form_input($attributes); ?>
</div`>
</div>
</div>
<div class='captcha-container'>
<div class='g-recaptcha' data-sitekey='<?= env('recaptcha2_sitekey'); ?>'></div>
</div>
<div class='form-footer'>
<?php $submit = [
'name' => 'loginSubmit',
'value' => 'Login',
'class' => 'submit-btn',
];?>
<?= form_submit($submit); ?>
</div>
<h4 style='text-align: center'>Not a member yet? Register
<a href= <?= site_url('users/register'); ?> title = 'Register'> HERE</a>
</h4>
<?= form_close(); ?>
</div>
It was a stupid mistake. Someone on the codeigniter forum answered my question here: CodeIgniter Forum
basically in my constructor I needed $this->userModel = new UserModel(); instead of $userModel = new UserModel();.

new Model fills updated_at

I am using Lumen and I just found an issue. When creating a new model, the code also fills 'updated_at' despite the model is new and it wasn't updated yet (since it was just created). Since this is a crucial flaw and would be strange that it wasn't noticed till now, I presume I am doing something wrong.
App\User.php:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
const CREATED_AT = 'date_created';
const UPDATED_AT = 'date_updated';
protected $fillable = [
'name',
'email',
'role_id',
'password'
];
protected $hidden = [
'token',
'password',
'date_password_reset',
'token_password_reset'
];
protected $casts = [
'date_created' => 'datetime:Uv',
'date_updated' => 'datetime:Uv',
'date_password_reset' => 'datetime:Uv'
];
protected $with = ['userRoles'];
protected $validationRules = [...];
}
App\Http\Controllers\UsersController.php:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use App\User;
use Illuminate\Validation\ValidationException;
use Exception;
class UsersController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
...
// first attempt
public function create(Request $request) {
$this->validate($request, (new User)->rules('create'));
$user = new User;
$user->name = $request->input('name');
$user->email = $request->input('email');
$user->password = Hash::make($request->input('password'));
$user->role_id = $request->input('role_id');
$user->active = $request->boolean('active');
$user->save();
return response()->json(
[
'success' => true,
'message' => 'User successfully created',
'data' => User::query()->find($user->id)
], 200);
}
// second attempt
public function create(Request $request) {
$this->validate($request, (new User)->rules('create'));
$user = new User;
$user->update($request->input());
$user->password = Hash::make($request->input('password'));
$user->active = $request->boolean('active');
$user->save();
return response()->json(
[
'success' => true,
'message' => 'User successfully created',
'data' => User::query()->find($user->id)
], 200);
}
// third attempt
public function create(Request $request) {
$this->validate($request, (new User)->rules('create'));
$user = new User($request->input());
$user->password = Hash::make($request->input('password'));
$user->active = $request->boolean('active');
$user->save();
return response()->json(
[
'success' => true,
'message' => 'User successfully created',
'data' => User::query()->find($user->id)
], 200);
}
}
DB migration:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Hash;
class CreateUsersTable extends Migration
{
protected $initialUsers = [
[
'name' => 'Administrator',
'email' => 'admin#localhost.local',
'password' => null,
'role_id' => null,
'active' => 1
]
];
protected $initialRoles = [
[
'name' => 'Administrator'
],
[
'name' => 'User'
]
];
protected $initialUserRoles = [];
public function up()
{
DB::beginTransaction();;
Schema::create('users_roles', function (Blueprint $table) {
$table->id();
$table->string('name', 50);
$table->timestamp('date_created')->useCurrent();
$table->timestamp('date_updated')->nullable()->default(DB::raw('NULL ON UPDATE CURRENT_TIMESTAMP'));
});
foreach ($this->initialRoles as $data) {
DB::table('user_roles')->insert($data);
}
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name', 100);
$table->string('email', 255)->unique();
$table->string('password');
$table->unsignedBigInteger('role_id')->nullable();
$table->string('token', 255)->nullable();
$table->tinyInteger('active');
$table->timestamp('date_password_reset')->nullable();
$table->string('token_password_reset')->nullable();
$table->timestamp('date_created')->useCurrent();
$table->timestamp('date_updated')->nullable()->default(DB::raw('NULL ON UPDATE CURRENT_TIMESTAMP'));
$table->foreign('role_id')->references('id')->on('users_roles')->onDelete('set null')->onUpdate('cascade');
});
$password = Hash::make('xxx#x');
$role_id = DB::table('users_roles')->where('name', 'Administrator')->value('id');
foreach ($this->initialUsers as $data) {
$data['password'] = $password;
$data['role_id'] = $role_id;
$user_id = DB::table('users')->insertGetId($data);
$this->initialUserRoles[] = [
'user_id' => $user_id,
'role_id' => $role_id
];
}
DB::commit();
}
}
Query created by Eloquent:
array (size=3)
'query' => string 'insert into `users` (`name`, `email`, `password`, `role_id`, `active`, `date_updated`, `date_created`) values (?, ?, ?, ?, ?, ?, ?)' (length=131)
'bindings' =>
array (size=7)
0 => string 'Test User 5' (length=11)
1 => string 'test6#test.net' (length=14)
2 => string '$2y$10$lvRGKuznotd8lqwCj2diIONGjyiAkhaNthWGjQyFWbBqiyuf20wpG' (length=60)
3 => string '1' (length=1)
4 => boolean true
5 => string '2020-06-17 10:30:07' (length=19)
6 => string '2020-06-17 10:30:07' (length=19)
'time' => float 5.5
All three create() attempts are filling up 'updated_at' despite that one should stay NULL until an actual update is done on this model. Can you guys give me any indication what am I doing wrong? Would also like to keep the $model->update($request->input()) functionality if possible, so that I do not need too assign each field manually.
Because Lumen/Laravel is handling the "created_at" and "updated_at" fields on it's own and it sets both to the same timestamp when a record is created (which I do not like), I created my own solution.
First is already in place when creating a migration. I created my own timestamp fields and those are already properly updated by MySQL:
$table->timestamp('date_created')->useCurrent();
$table->timestamp('date_updated')->nullable()->default(DB::raw('NULL ON UPDATE CURRENT_TIMESTAMP'));
And of course, disable timestamp handling for Lumen in User.php model:
public $timestamps = false;
But in case that this is not possible for any reason or if you want Lumen/Laravel to handle those, this is the code I wrote in User.php model:
const CREATED_AT = 'date_created';
const UPDATED_AT = 'date_updated';
public $timestamps = false;
public static function boot() {
parent::boot();
static::creating(function ($model) {
$model->{self::CREATED_AT} = $model->freshTimestamp();
});
static::updating(function ($model) {
$model->{self::UPDATED_AT} = $model->freshTimestamp();
});
}

Silverstripe populate form based on url

I have TeamsPage class and Team class. I am trying to figure out how to pre-populate the form with the data from the database based on the ID that was passed in the URL. Below is the code of my attempt, I tried to pass in the ID via template but that did not work. How else can I accomplish this? I would prefer if there was a way to pass the team as an object that I already have in the edit function so that I don't have to hit the database twice. Is there a way to do this?
TeamsPage:
<?php
class TeamsPage extends Page {
private static $has_many = array (
'Teams' => 'Team',
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Teams', GridField::create(
'Teams',
'Teams on this page',
$this->Teams(),
GridFieldConfig_RecordEditor::create()
));
return $fields;
}
}
class TeamsPage_Controller extends Page_Controller {
private static $allowed_actions = array (
'show', 'edit', 'EditTeamForm'
);
public function EditTeamForm($teamId){
$fields = new FieldList(
new TextField('TeamName'),
new TextareaField('TeamDescription')
);
$actions = new FieldList(
new FormAction('EditTeam', 'Save Changes')
);
$requiredFields = new RequiredFields(array('TeamName','TeamDescription'));
$form = new Form($this, 'EditTeamForm', $fields, $actions, $requiredFields);
$form->setFormMethod('POST', true);
$data = Session::get("FormData.{$form->getName()}.data");
$team = Team::get()->byID($teamId);
return $data ? $form->loadDataFrom($data) : $form->loadDataFrom($team);
}
public function show(SS_HTTPRequest $request) {
$team = Team::get()->byID($request->param('ID'));
if(!$team) {
return $this->httpError(404,'That team could not be found');
}
return array (
'Team' => $team
);
}
public function edit(SS_HTTPRequest $request){
$team = Team::get()->byID($request->param('ID'));
if(!$team) {
return $this->httpError(404,'That team could not be found');
}
return array (
'Team' => $team
);
}
}
Team:
<?php
class Team extends DataObject {
private static $db = array(
'TeamCaptain' => 'Int',
'TeamName' => 'Varchar',
'TeamDescription' => 'Text'
);
private static $has_one = array (
'Photo' => 'Image',
'TeamsPage' => 'TeamsPage'
);
private static $summary_fields = array (
'GridThumbnail' => '',
'TeamCaptain' => 'Team Captain',
'TeamName' => 'TeamName',
'TeamDescription' => 'Team Description',
);
public function getGridThumbnail() {
if($this->Photo()->exists()) {
return $this->Photo()->SetWidth(100);
}
return '(no image)';
}
public function getCMSFields() {
$fields = FieldList::create(
TextField::create('TeamCaptain'),
TextField::create('TeamName'),
TextareaField::create('TeamDescription'),
$uploader = UploadField::create('Photo')
);
$uploader->setFolderName('teams-photos');
$uploader->getValidator()->setAllowedExtensions(array(
'png','gif','jpeg','jpg'
));
return $fields;
}
public function Link() {
return $this->TeamsPage()->Link('show/'.$this->ID);
}
}
TeamsPage_edit.ss
<% if GetMember() %>
Welcome $getMember.FirstName<br />
$EditTeamForm($ID)
Back to Home
<% else %>
$GoToLogin()
<% end_if %>
It looks to me like you're passing the wrong ID to EditTeamForm from the template. Unless there is a <% with %> statement that I'm not seeing I think you want to call:
$EditTeamForm($Team.ID)
Everything else looks fine to me.

InputFilter "setRequired" not working for html5 multiple

I'm having hard time with a weird behaviour of fileinput.
This is my form:
namespace Frontend\Form;
use NW\Form\Form;
use Zend\InputFilter;
use Zend\Form\Element;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
class EnrollStructure extends Form implements ServiceManagerAwareInterface
{
protected $sm;
public function __construct($name=null) {
parent::__construct("frmEnrollStructure");
$this->setAttribute("action", "/registrazione_struttura/submit")
->setAttribute('method', 'post')
->setAttribute("id", "iscrizione_struttura")
->setAttribute("class", "form fullpage");
$this->addInputFilter();
}
public function init()
{
$structureFs = $this->sm->get('Structure\Form\Fieldsets\Structure');
$structureFs->setUseAsBaseFieldset(true);
$structureFs->remove("id")
->remove("creationTime")
->remove("latLon");
$file = new Element\File("images");
$file->setAttribute('multiple', true);
$this->add($structureFs)->add($file);
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Iscriviti',
'id' => 'sbmtEnrollStructure',
'class' => 'submit_btn'
),
));
$this->setValidationGroup(
array(
'structure' =>
array(
'companyname',
'vatNumber',
'addressStreet',
'addressZip',
'addressCity',
'addressRegion',
'fax',
'publicPhone',
'publicEmail',
'website',
'status',
'ownerNotes',
'category',
'subcategory',
"facilities",
"agreeOnPolicy",
"agreeOnPrivacy",
"subscribeNewsletter",
"contact" => array("name", "surname", "email", "role", "phone"),
),
"images"
));
}
/**
* Set service manager
*
* #param ServiceManager $serviceManager
*/
public function setServiceManager(ServiceManager $serviceManager)
{
$this->sm = $serviceManager;
}
public function addInputFilter()
{
$inputFilter = new InputFilter\InputFilter();
// File Input
$fileInput = new InputFilter\FileInput('images');
$fileInput->setRequired(true);
$fileInput->getValidatorChain()
->attachByName('filesize', array('max' => "2MB"))
->attachByName('filemimetype', array('mimeType' => 'image/png,image/x-png,image/jpg,image/jpeg'))
->attachByName('fileimagesize', array('maxWidth' => 2048, 'maxHeight' => 2048));
$inputFilter->add($fileInput);
$this->setInputFilter($inputFilter);
}
}
Basically, I mainly use a fieldset which contains most of the data I request to the user, plus a File input field.
This is the Fieldset Structure: (most important parts..)
use Zend\Form\Element;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Validator\Identical;
use Zend\Validator\NotEmpty;
use Zend\Validator\Regex;
use Zend\Validator\StringLength;
class Structure extends Fieldset implements InputFilterProviderInterface, ServiceManagerAwareInterface
{
protected $sm;
public function __construct()
{
parent::__construct('structure');
}
public function init()
{
$this->setHydrator(new DoctrineHydrator($this->_entityManager(),'Structure\Entity\Structure'));
$this->setObject($this->sm->getServiceLocator()->get("Structure_Structure"));
$id = new Element\Hidden("id");
$name = new Element\Text("companyname");
$name->setLabel("Ragione Sociale");
...........
}
public function getInputFilterSpecification()
{
return array
(
"id" => array(
"required" => false,
),
"companyname" => array(
"required" => true,
"validators" => array(
array('name' => "NotEmpty", 'options' => array("messages" => array( NotEmpty::IS_EMPTY => "Inserire la ragione sociale")))
),
),
.....
}
}
This is my controller:
public function submitAction()
{
try {
$this->layout("layout/json");
$form = $this->getForm('Frontend\Form\EnrollStructure');
//$form->addInputFilter();
$structure = $this->getServiceLocator()->get("Structure_Structure");
$viewModel = new ViewModel();
$request = $this->getRequest();
if ($request->isPost())
{
$post = array_merge_recursive
(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
);
$form->setData($post);
if ($form->isValid())
{
$structure = $form->getObject();
$contact = $structure->getContact();
$this->getServiceLocator()->get('Structure_ContactService')->save($contact);
$files = $request->getFiles()->toArray();
if(isset($files['images']))
{
$count = 3;
foreach($files['images'] as $pos => $file)
{
$fpath = $this->getServiceLocator()->get('RdnUpload\Container')->upload($file);
if(!empty($fpath))
{
if(--$count ==0) break;
$asset = $this->getServiceLocator()->get("Application_AssetService")->fromDisk($fpath, $file['name']);
$this->getServiceLocator()->get("Application_AssetService")->save($asset);
$structure->addImage($asset);
}
}
}
$this->getServiceLocator()->get('Structure_StructureService')->save($structure);
$retCode = RetCode::success(array("iscrizione_struttura!" => array("form_submit_successfull")), true);
}
else
{
$messages = $form->getMessages();
if(empty($messages))
$retCode = RetCode::error(array("iscrizione_struttura" => array("need_at_least_one_file" => "missing file")), true);
else
$retCode = RetCode::error(array("iscrizione_struttura" => $messages), true);
}
$viewModel->setVariable("retcode", $retCode);
return $viewModel;
}
} catch(Exception $e)
{
throw $e;
}
}
The strange thing is that if i remove from the field "images" the "multiple" attribute everything works fine, causing the form not to validate and i get this message:
[images] => Array
(
[fileUploadFileErrorFileNotFound] => File was not found
)
While, if i set the attribute multiple, and the user does not upload a file i get no error, but the form gets invalidated (this is the reason for this "bad" code in my controller:)
$messages = $form->getMessages();
if(empty($messages))
$retCode = RetCode::error(array("iscrizione_struttura" => array("need_at_least_one_file" => "missing file")), true);
else
$retCode = RetCode::error(array("iscrizione_struttura" => $messages), true);
I found the problem was caused by the Jquery form plugin, without it it works fine. :( In case somebody needs, I think the correct action code can be found here (I haven't tryied it anyway)
https://github.com/cgmartin/ZF2FileUploadExamples/blob/master/src/ZF2FileUploadExamples/Controller/ProgressExamples.php

How to add both Form and List to $this [Plesk/Zend]

I have some sample code with 2 tabs. One shows a "form" and the other a "list" (Sample 1.5-1), I want to combine them.
I want to show the "form" tab with a "list" view at the bottom (after submit button). I am getting stuck on how to show this.
Inside IndexController, in the ->getRequest->isPost() area, I try to create and fill up the $list (same as the "list" tab example code):
$list=$this->_getListRandom();
$this->view->list = $list;
Then inside of form.phtml, I append:
<h1>My Report Data></h1>
<?php echo $this->list; ?>
I can see the "My Report Data" text in the web page, so I know I am getting to the right area in the code!
But, I get an error from pm_View_Helper_render::renderList() that it must be an instance of pm_View_List_Simple.
I am trying to create both a pm_Form_Simple and pm_View_List_Simple in the same $this, but not
sure if it is allowed or how to do it.
Thanks for any suggestions!
<?php
class IndexController extends pm_Controller_Action
{
public function init()
{
parent::init();
// Init title for all actions
$this->view->pageTitle = 'Example Module';
// Init tabs for all actions
$this->view->tabs = array(
array(
'title' => 'Form',
'action' => 'form',
),
array(
'title' => 'List',
'action' => 'list',
),
);
}
public function indexAction()
{
// Default action will be formAction
$this->_forward('form');
}
public function formAction()
{
// Init form here
$form = new pm_Form_Simple();
$form->addElement('text', 'exampleText', array(
'label' => 'Example Text',
'value' => pm_Settings::get('exampleText'),
'required' => true,
'validators' => array(
array('NotEmpty', true),
),
));
$form->addControlButtons(array(
'cancelLink' => pm_Context::getModulesListUrl(),
));
if ($this->getRequest()->isPost() && $form->isValid($this->getRequest()->getPost())) {
// Form proccessing here
pm_Settings::set('exampleText', $form->getValue('exampleText'));
$this->_status->addMessage('info', 'Data was successfully saved.');
# Create the LIST
$list = $this->_getListRandom();
$this->view->list = $list;
$this->_helper->json(array('redirect' => pm_Context::getBaseUrl()));
}
$this->view->form = $form;
}
public function listAction()
{
$list = $this->_getListRandom();
// List object for pm_View_Helper_RenderList
$this->view->list = $list;
}
public function listDataAction()
{
$list = $this->_getListRandom();
// Json data from pm_View_List_Simple
$this->_helper->json($list->fetchData());
}
private function _getListRandom()
{
$data = array();
#$iconPath = pm_Context::getBaseUrl() . 'images/icon_16.gif';
for ($i = 0; $i < 15; $i++) {
$data[] = array(
'column-1' => '' . (string)rand() . '',
'column-2' => (string)rand(),
);
}
$list = new pm_View_List_Simple($this->view, $this->_request);
$list->setData($data);
$list->setColumns(array(
'column-1' => array(
'title' => 'Random with link',
'noEscape' => true,
),
'column-2' => array(
'title' => 'Random with image',
'noEscape' => true,
),
));
// Take into account listDataAction corresponds to the URL /list-data/
$list->setDataUrl(array('action' => 'list-data'));
return $list;
}
}
Please, try https://mega.co.nz/#!NxtyzbyS!JQqFdh7ruESQU_pgmhM6vi8yVFZQRTH-sPDeQcAOFws
Following files are changed:
\example-1.5-2\plib\views\scripts\index\form.phtml:
<?php echo $this->renderTabs($this->tabs); ?>
<?php echo $this->test; ?>
<?php echo $this->form; ?>
<?php echo $this->renderList($this->list); ?>
\example-1.5-2\plib\controllers\IndexController.php:
public function formAction() {
...
...
...
$list = $this->_getListRandom();
// List object for pm_View_Helper_RenderList
$this->view->list = $list;
}
and here the result: