Doctrine: row too large when submitting - mysql

I have a class Person with about 100 fields.
recently i added a new field:
/**
*
* #ORM\Entity
* #Vich\Uploadable
* #ORM\Entity(repositoryClass="My\VenderBundle\Repository\PersonRepository")
* #ORM\Table(name="my_vendor_person")
*/
class Person
{
....
/**
* My new property
*
* #var array $references
*
* #ORM\Column(name="references", type="array", nullable=true)
*/
protected $references;
The form type has been updated accordingly:
class PersonInvitationType extends AbstractType
{
private $context;
/**
* PersonNewType constructor.
* #param AuthorizationChecker $securityContext
*/
public function __construct(AuthorizationChecker $securityContext)
{
$this->context = $securityContext;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('references', CollectionType::class, array(
'entry_type' => Referencese::class,
'label' => 'References',
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'prototype_name' => 'references__name__',
'by_reference' => false,
'required' => false
))
But now I am getting the following error when submitting a form containing almost all fields of class Person:
An exception occurred while executing 'UPDATE my_vendor_person
SET references = ? WHERE id = ?' with params
["a:1:{s:7:\"myProperty0\";a:4:{s:4:\"name\";s:7:\"my name\";s:6:\"location\";
s:9:\"my location\";s:5:\"phone\";s:8:\"90898978978\";s:5:\"email\";
s:17:\"myemail#gmail.com\";}}", 765]:
Below that, the following is stated:
QLSTATE[42000]: Syntax error or access violation: 1118 Row size too large
(> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or
ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored
inline.
The form contains more fields of type array which contain more information then the above example. someone has an idea of what is happening here? Am Running Symfony 3.
UPDATE:
please find a pastbin of the dev.log here: http://pastebin.com/0qLm60x7
SECOND UPDATE:
please find the create table statement here: http://pastebin.com/PFy5jAbx

Related

How to store activity log in mongo db from laravel?

I am using spatie/laravel-activitylog to log the activities and jenssegers/laravel-mongodb connect to a Mongo database. In user Model, the user data is storing into mysql and log data need to be stored in mongodb. I am getting "Call to a member function prepare() on null"
config/activitylog.php
` /*
* This is the database connection that will be used by the migration and
* the Activity model shipped with this package. In case it's not set
* Laravel's database.default will be used instead.
*/
'database_connection' => env('ACTIVITY_LOGGER_DB_CONNECTION'),`
database.php
`'mongodb' => [
'driver' => 'mongodb',
'host' => '127.0.0.1',
'port' => '27017',
'database' => 'test_log',
'username' => '',
'password' => '',
'options' => [
'database' => 'admin'
]
],`
.env
`ACTIVITY_LOGGER_DB_CONNECTION=mongodb`
App\Models\User.php
`<?php
namespace App\Models;
// use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;
use Jenssegers\Mongodb\Auth\User as Authenticatable;
class User extends Authenticatable implements MustVerifyEmail
{
use LogsActivity;
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [];
/**
* The attributes that should be hidden for serialization.
*
* #var array<int, string>
*/
/**
* The attributes that should be cast.
*
* #var array<string, string>
*/
/**
* The attributes that should be mutated to dates.
*
* #var array
*/
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults();
}
}
`
In user Model, the user data is storing into mysql and log data need to be stored in mongodb.
The error message "Call to a member function prepare() on null" usually occurs when the database connection is not properly configured or the database connection does not exist.
In this case, you have set the database connection for the activity logs in the config/activitylog.php and .env files. However, it seems that the database connection is not being used properly in the User model.
To resolve this issue, you need to ensure that the database connection defined in 'config/activitylog.php' is being passed to the User model when logging activities.
You can add the following code to your User model to explicitly set the database connection:
use Illuminate\Support\Facades\Config;
protected static $logConnection = 'mongodb';
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults()->using(Config::get('activitylog.database_connection') ?: static::$logConnection);
}
This will make sure that the activity logs are stored in the MongoDB database defined in the mongodb connection in config/database.php.
Fixed the issue with the help of this tutorial:: https://nickdevs.wordpress.com/2022/05/17/laravel-laravel-activitylog-inegrate-activity-log-with-mongodb/
The issue was with Spatie-activity-log and Jenssegers MongoDB. Spatie-activity-log uses default Model. We need to overwrite the Spatie Activity Model for Jenssegers MongoDB.
Create Activity.php in App/Models. copy the existing code from Spatie\Activitylog\Models\Activity.php from vendor/spatie/laravel-activitylog/src/Models/Activity.php. Replace the lines listed below.
remove:
namespace Spatie\Activitylog\Models;
use Illuminate\Database\Eloquent\Model;
class Activity extends Model implements ActivityContract
add:
namespace App\Models;
use Jenssegers\Mongodb\Eloquent\Model as MongoDBModel;
class Activity extends MongoDBModel implements ActivityContract

How do I verify a hash code exists in MySQL table using Laravel 8

I want to be able to verify comfirm row with specific hashcode exists in a table before a user bearing the given hash code can fill a registration form.
I know the hash code exists because it's in the database. But the application redirect to the page it should if the hash code is non-existent and outputs a message that the hash code doesn't exist.
This used to work in Laravel 5 but it seems the implementation has changed since Laravel 8.
Here's my code:
use App\Http\Controllers\Site\Guest\newMembership\RegistrationForm;
...
Route::get('registration/{hashCode}', [RegistrationForm::class, 'registrationForm'])->name('registration');
Route::post('registration', [RegistrationForm::class, 'registrationProcessing'])->name('registration_data');
My controller, RegistrationForm.php has the code:
namespace App\Http\Controllers\Site\Guest\newMembership;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class RegistrationForm extends Controller
{
public function registrationForm($hashCode)
{
// Check if this $hashCode exists at all, otherwise redirect to referral request home page.
$hash_exists = (new \App\Http\Controllers\Site\Guest\newMembership\Form)->hashExists($hashCode);
// In the event the number of times it occurs is zero
if($hash_exists < 1)
{
// Tell user the referral link is non-existent.
session()->flash('membershipInfo', 'Your code does not exist.');
// Take this user to the referral request welcome page
return redirect()->route('membership.index');
}
// Assign new variable name to hash code
$referralCode = $hashCode;
return view('membership.registration', [
'referralCode' => $referralCode,
]);
}
The Form contoller has the code:
// Import database model
use App\Models\Site\Guest\Referralrequestapplication;
...
/**
* Count number of entries with given ID
*/
public function hashExists($hashCode)
{
//DB::table('referralrequestapplications')
Referralrequestapplication::where(['blocked', 0], ['image_reference', $hashCode])->count();
}
The model code:
namespace App\Models\Site\Guest;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Referralrequestapplication extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'blocked', 'review', 'reviewer', 'firstname', 'surname', 'phone', 'email', 'nin', 'facebook', 'twitter', 'instagram', 'state', 'city', 'neighbourhood', 'address', 'image_reference', 'created_at', 'updated_at',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $table = 'referralrequestapplications';
}
The migration schema has the code:
Schema::create('referralrequestapplications', function (Blueprint $table) {
$table->bigIncrements('id');
$table->boolean('blocked')->default(0);
$table->boolean('reviewed')->default(0);
$table->string('reviewer')->nullable();
$table->string('firstname', 30)->nullable();
$table->string('surname', 30)->nullable();
$table->string('phone', 30)->nullable();
$table->string('email', 70)->nullable();
$table->string('nin', 20)->nullable();
$table->string('facebook', 70)->nullable();
$table->string('twitter', 70)->nullable();
$table->string('instagram', 70)->nullable();
$table->string('state', 40)->nullable();
$table->string('city', 40)->nullable();
$table->string('neighbourhood', 40)->nullable();
$table->string('address', 200)->nullable();
$table->string('image_reference', 200)->nullable();
$table->timestamps();
});
I fixed this issue by changing the code in Form controller from:
Referralrequestapplication::where(['blocked', 0], ['image_reference', $hashCode])->count();
To:
Referralrequestapplication::where('blocked', 0)->where('mage_reference', $hashCode)->exists();
Also I changed the following in RegistrationForm controller:
if($hash_exists < 1)
To:
if($hash_exists = 0)

Select related rows in Yii2

I have related tables (table train_schedule have departute_station_id and arrival_station_id) linked on Station:
enter image description here
I want select records from train_schedule with stations name:
$trainsTchedule = TrainSchedule::find()
->joinWith('getArrivalStation')
->joinWith('getDepartuteStation()')
->all();
In TrainSchedule class:
/**
* #return \yii\db\ActiveQuery
*/
public function getArrivalStation()
{
return $this->hasOne(Station::className(), ['id' => 'arrival_station_id']);
}
And
/**
* #return \yii\db\ActiveQuery
*/
public function getDepartuteStation()
{
return $this->hasOne(Station::className(), ['id' => 'departute_station_id']);
}
Error:
Relation names are case sensitive. app\models\TrainSchedule has a
relation named "arrivalStation" instead of "ArrivalStation".
Howe get data wrom linked tables?
You have defined your relations correctly but, you are calling them incorrectly. Your relation
getArrivalStation should be specified as arrivalStation
getDepartuteStation() should be departuteStation
when specifying in the joinWith, and you need to provide an array if you need to specify multiple relations when calling joinWith as currently your second call ->joinWith('getDepartuteStation()') is overriding the previous one ->joinWith('getArrivalStation').
So the query should look like below
$trainsTchedule = TrainSchedule::find()
->joinWith(['arrivalStation','departuteStation'])
->all();
You should read about Working with Relational Data

Yii2 Access Rules Using Different Models

I'm having trouble with Yii2 Role Based Access Control. In the usual set-up, the authentication rule takes place when the identity of the current user. Like written in the docs. Authorization
In my case, how can I set up the authorization (aside from the basic feature) using another set of models.? Here is my set up.
Table auth_assignment [item_name, user_id] from rbac migration,
user [id] from the yii2 migration.
I created a new table assignment [user_id related to user, rec_id related to recognition of an organization].
This is the scenario. I have the roles admin, organization-head, member. How can I check if the organization-head, or member belongs to their own Recognition module; not the other modules from other organization-heads?
I used also the context access control filter by peixoto.
Here is my code for checking. RecognitionRule checks if there is a user user_id equal to the identity of the user; and account_id equal to rec_id. The second condition tells if he is belong to the organization
/**
* Checks if ID matches user passed via params
*/
class RecognitionRule extends Rule
{
public $name = 'isRecognition';
/**
* #param string|integer $user the user ID.
* #param Item $item the role or permission that this rule is associated with
* #param array $params parameters passed to ManagerInterface::checkAccess().
* #return boolean a value indicating whether the rule permits the role or permission it is associated with.
*/
public function execute($user, $item, $params)
{
if(isset($params['recognition'])){ //Directly specify the model you plan to use via param
$model = $params['recognition'];
}else{ //Use the controller findModel method to get the model - this is what executes via the behaviour/rules
$id = Yii::$app->request->get('id'); //Note, this is an assumption on your url structure.
$model = Yii::$app->controller->findModel($id); //Note, this only works if you change findModel to be a public function within the controller.
}
return \common\models\Assignment::find()->where(['rec_id' => $model->id, 'user_id' => $user])->exists();
}
}
Still, I am not allowed to perform the action. Any clues?
I got the answers. I based my answer on AccessRule behavior and rbac\Rule $params
snippet of the RecognitionRule
/**
* #param string|integer $user the user ID.
* #param Item $item the role or permission that this rule is associated with
* #param array $params parameters passed to ManagerInterface::checkAccess().
* #return boolean a value indicating whether the rule permits the role or permission it is associated with.
*/
public function execute($user, $item, $params)
{
if(isset($params['recognition'])){ //Directly specify the model you plan to use via param
$model = $params['recognition'];
} else{ //Use the controller findModel method to get the model - this is what executes via the behaviour/rules
$id = Yii::$app->request->get('id'); //Note, this is an assumption on your url structure.
}
return \common\models\Assignment::find()->where(['rec_id' => $id, 'user_id' => $user])->exists();
}
}
?>
RecognitionController
[
'class' => 'common\rbac\ContextAccessRule',
'modelClass' => 'frontend\models\recognition',
'allow' => true,
'actions' => ['view','update'],
'roles' => ['viewOwnRecognition', 'updateOwnRecognition'],
],
],
],
];

How to use Zend Adapter to retrieve information from database

I'm trying to figure out the essentials of Zend Adapter. The tutorials and explanations are confusing and needs more clarification. Can someone give me simple examples to fully understand how to work with SQL queries and how to get the desired SQL results?
especially, I'm interested in learning how to get
-- column names
-- table names
-- fetchAll entries
and etc.
Thank you,
Like a lot of other people you seem to be having difficulty with the quickstart, try the tutorial from Rob Allen it helped me get started.
You have multiple choices on how to connect to your table, the confusion with Zend_Db often begins here.
The easiest way when using one DB, in your application.ini file add these lines at a minmum:
resources.db.adapter = "pdo_Mysql"
resources.db.params.username = "user_name"
resources.db.params.password = "password"
resources.db.params.dbname = "db_name"
Alternatively you can connect to a database almost anywhere in your code using the Zend_Db_Adapter:
//using a normal constructor
$db = new Zend_Db_Adapter_Pdo_Mysql(array(
'host' => '127.0.0.1',
'username' => 'webuser',
'password' => 'xxxxxxxx',
'dbname' => 'test'
));
//using factory
$db = Zend_Db::factory('Pdo_Mysql', array(
'host' => '127.0.0.1',
'username' => 'webuser',
'password' => 'xxxxxxxx',
'dbname' => 'test'
));
List of supported Databases
Using this in your application can be as simple as:
//fetchAll using Zend_Db_Adapter and plain SQL
$sql = 'SELECT * FROM bugs WHERE bug_id = ?';
$result = $db->fetchAll($sql, 2);
you can list the tables in a database:
$tables = $db->listTables();
or you can get a full table description (including column names), I included the comment block from the function in Zend_Db_Adapter_Abstract:
/**
* Returns the column descriptions for a table.
*
* The return value is an associative array keyed by the column name,
* as returned by the RDBMS.
*
* The value of each array element is an associative array
* with the following keys:
*
* SCHEMA_NAME => string; name of database or schema
* TABLE_NAME => string;
* COLUMN_NAME => string; column name
* COLUMN_POSITION => number; ordinal position of column in table
* DATA_TYPE => string; SQL datatype name of column
* DEFAULT => string; default expression of column, null if none
* NULLABLE => boolean; true if column can have nulls
* LENGTH => number; length of CHAR/VARCHAR
* SCALE => number; scale of NUMERIC/DECIMAL
* PRECISION => number; precision of NUMERIC/DECIMAL
* UNSIGNED => boolean; unsigned property of an integer type
* PRIMARY => boolean; true if column is part of the primary key
* PRIMARY_POSITION => integer; position of column in primary key
*
* #param string $tableName
* #param string $schemaName OPTIONAL
* #return array
*/
$describTable = $db->describeTable('myTable');
This info should get you started, however I find that a lot of the real power of Zend_Db resides in the Zend_Db_Table, Zend_Db_Table_Row and especially the Zend_Db_Select classes.
I urge you to take some time and figure them out.
As an example of what you might expect from Zend_Db_Table and Zend_Db_select (when not using more advanced mappers and domain objects, hopefully those will come later):
//When using DbTable models that extend Zend_Db_Table_Abstract the model already
//knows the name of the table and has full access to the Db adapter, allowing your code to
//be very brief and descriptive.
class Application_Model_DbTable_Weekend extends Zend_Db_Table_Abstract
{
//name of table, required if classname is not the same as the table name
protected $_name = 'weekend';
//primary key column of table, a good idea especially if primary key is not 'id'
protected $_primary = 'weekendid';
public function getWeekend($weekendId) {
//create select object
$select = $this->select();
$select->where('weekendid = ?', $weekendId);//placeholder syntax
$result = $this->fetchRow($select);
if (!$result) {
throw new Exception('Could not find weekend ID ' . $weekendId);
}
return $result;//returns a single row object
}
public function fetchAllWeekend() {
$select = $this->select();
$result = $this->fetchAll($select);
return $result; //returns array of row objects (rowset object)
}
}
Rob Allen's Zf tutorial will explain how DbTable models are setup and how they Work.
hope this helps...