How to reinstall database on Prestahop Module? - php

I'm trying to customize a Prestashop module and I need to add two new colonnes in a table.
The problem is that the database is already created, I guess it did when the module initializing. So if I change the code now, changes does not appear and I keep receiving this mistake:
There is no way to do it in configuration and I suppose if I delete the module my code will dissepear.
How can I do ?
Maybe asking the delete and the create method in a common method (just one time).
I'm new with Smarty and PHP, I see it's not a usual method where the table is created.
Could you help me ?
I'm new with Smarty, how can I do that ?
It looks like it's not a method where the table is created.
$sql = array();
$sql[] =
'CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'opartdevis` (
`id_opartdevis` int(10) NOT NULL AUTO_INCREMENT,
`id_shop` int(10) NOT NULL,
`id_cart` int(10) NOT NULL,
`id_customer` int(10) NOT NULL,
`name` varchar(128),
`message_visible` TEXT,
`id_customer_thread` int(10),
`date_add` DATETIME NOT NULL,
`status` int(2) DEFAULT 0,
`id_order` int(10) NULL,
`id_ordered_cart` int(10) NULL,
`remise` int(10),
`delivery` int(10),
PRIMARY KEY (`id_opartdevis`)
) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=utf8';
//1.6.1.0 specific price bug fix
if (version_compare(_PS_VERSION_, '1.6.1.0', '=')) {
$sql[] = "ALTER TABLE "._DB_PREFIX_."specific_price DROP INDEX id_product_2";
$sql[] = "ALTER TABLE "._DB_PREFIX_."specific_price ADD INDEX id_product_2 (id_product,id_shop,id_shop_group,id_currency,id_country,id_group,id_customer,id_product_attribute,from_quantity,id_specific_price_rule,id_cart,`from`,`to`)";
}
foreach ($sql as $s) {
if (!Db::getInstance()->execute($s)) {
return false;
}
}
Thanks in advance
Malaury

You need to revert all DB changes when you're uninstalling the module.
Define (or append to existing) uninstall() function in your base module file and run DROP TABLE query on the created table. Example:
public function uninstall() {
if (!parent::uninstall()) {
return false;
}
$sql = 'DROP TABLE IF EXISTS `'._DB_PREFIX_.'opartdevis`';
if (!Db::getInstance()->execute($sql)) {
return false;
}
return true;
}
This way, when you're uninstalling the module, the table is going to be deleted (and recrteated when you install it again).

Related

Wordpress - save data from own plugin

My own wordpress plugin generates this data of a file:
filename|creator|date
This is my filename|Max Mustermann|20.11.2017
This is my filename|Anne Mustermann|26.11.2017
This is my filename|Alex Mustermann|27.11.2017
How is wordpress built to save this data? How do I do that the right way?
Thanks for your answers!
Lingo
Try this example,
function bot_install()
{
global $wpdb;
$table = $wpdb->prefix."bot_counter";
$structure = "CREATE TABLE $table (
id INT(9) NOT NULL AUTO_INCREMENT,
bot_name VARCHAR(80) NOT NULL,
bot_mark VARCHAR(20) NOT NULL,
bot_visits INT(9) DEFAULT 0,
UNIQUE KEY id (id)
);";
$wpdb->query($structure);
// Populate table
$wpdb->query("INSERT INTO $table(bot_name, bot_mark)
VALUES('Google Bot', 'googlebot')");
$wpdb->query("INSERT INTO $table(bot_name, bot_mark)
VALUES('Yahoo Slurp', 'yahoo')");
}
You get the result.

Eloquent BelongsToMany Relationship searches for is null

I have 3 tables artist, catalog & cat_artist (pivot table). When retrieving a row from my catalog table I want to get all the associated artists with it. I could just do this with raw sql but since using laravel it feels wrong because it has many of the functions to do this already. So I have a the function in my product model (product modal references the catalog table) to create the join
public function artists()
{
return $this->belongsToMany('App\Artist', 'cat_artist', 'LOOK_UP_TO_CAT_ID', 'LOOK_UP_TO_ARTIST_ID');
}
I then call this before I return my view which gives me the the row from my catalog table
$product = Product::find($id);
Now I want to get all the artists that may belong to this product aswell so I call the following
$artists = $product->artists()->get();
This returns an emtpy result set
Here is the query log from the above
array(2) {
[0]=> array(3) {
["query"]=> string(60) "select * from `catelogue` where `catelogue`.`id` = ? limit 1"
["bindings"]=> array(1) {
[0]=> int(96033)
}
["time"]=> float(0.91)
}
[1]=> array(3) {
["query"]=> string(289) "select `artist`.*, `cat_artist`.`LOOK_UP_TO_CAT_ID` as `pivot_LOOK_UP_TO_CAT_ID`, `cat_artist`.`LOOK_UP_TO_ARTIST_ID` as `pivot_LOOK_UP_TO_ARTIST_ID` from `artist` inner join `cat_artist` on `artist`.`id` = `cat_artist`.`LOOK_UP_TO_ARTIST_ID` where `cat_artist`.`LOOK_UP_TO_CAT_ID` is null"
["bindings"]=> array(0) { }
["time"]=> float(0.37) } }
This is all happening before I return the view and pass the data to the view
Everything else in the query is right apart from this where it's looking for null
where `cat_artist`.`LOOK_UP_TO_CAT_ID` is null
It should be this
where `cat_artist`.`LOOK_UP_TO_CAT_ID` = ?
Please help. I can't figure out where I have gone wrong
EDIT
Here are my DB tables - watered down as showing all cols would be a waste
CREATE TABLE IF NOT EXISTS `artist` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`ARTIST` varchar(255) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `ARTIST` (`ARTIST`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
CREATE TABLE `catelogue` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`CAT_NO` varchar(255) DEFAULT NULL,
`TITLE` varchar(255) DEFAULT NULL,
`BARCODE` varchar(15) DEFAULT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `BARCODE` (`BARCODE`),
UNIQUE KEY `CAT_NO` (`CAT_NO`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cat_artist` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`LOOK_UP_TO_CAT_ID` int(11) NOT NULL,
`LOOK_UP_TO_ARTIST_ID` int(11) NOT NULL DEFAULT '1',
PRIMARY KEY (`ID`),
UNIQUE KEY `unique_index` (`LOOK_UP_TO_CAT_ID`,`LOOK_UP_TO_ARTIST_ID`),
KEY `LOOK_UP_TO_CAT_ID` (`LOOK_UP_TO_CAT_ID`),
KEY `LOOK_UP_TO_ARTIST_ID` (`LOOK_UP_TO_ARTIST_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Hopefully an answer can be found as to why it is putting is null in the where statement rather than the product ID
Also I have tested the resulting raw SQl by replacing is null with a product id and it does work in phpMyAdmin so the SQL been generated is correct up to the is null
This may sounds stupid, but I think it's beacuse your field names are in uppercase letters. so laravel cannot find the id column in attributes list in Project model. so it assumes you are search for null ids.
So at least rename ID columns to id(lowercase).
After lots of digging I found that I was using the wrong var to set the $primaryKey. I was using $primary_id. How or where I picked this up I don't know but it seems to be the root cause because I wasn't changing the primaryKey var but rather declaring a new one - Stupid user error
To Any one else finding this - double check your code.
Make sure you are assigning the correct variable.
Wrapping a pre tag around my var_dump helps to read a large obeject/array and helped me to find the issue

How to lock a table during an operation use php/yii

My table:
CREATE TABLE IF NOT EXISTS `detail_transaction` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`created_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`code` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`id_product` int(11) NOT NULL,
`id_store` int(11) NOT NULL,
`input_quality` int(11) NOT NULL,
`output_quality` int(11) NOT NULL,
`quality_in_store` int(11) NOT NULL,
PRIMARY KEY (`id`)
)
I have the problem is below:
I get record have max_id, and then before i insert new record, having
another process insert new record was inserted.
I think: I will lock table during "I select a record have max_id" to "I completed to insert new next record"(don't run any task work with this table). And to do this method. Please help me! How to do this by php code or Yii.
You could use transactions:
$transaction = Yii::app()->db->beginTransaction();
try {
foreach ($items as $item) {
$item->attr = value;
$item->save();
}
$transaction->commit();
// actions to do on success (redirect, alert, etc.)
} catch (Exception $e) {
$transaction->rollBack();
// other actions to perform on fail (redirect, alert, etc.)
}
This source code is from this post: using transaction in a loop in yii
I'm not exactly sure what you want to achieve, but I'm sure it will work out if you just use transactions - http://www.yiiframework.com/doc-2.0/yii-db-transaction.html. Otherwise, you can always call a LOCK TABLE query - http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html.
$connection = Yii::app()->db;
$lock = $connection-> createCommand('LOCK TABLES `detail_transactions` WRITE');
// do your magic
$unlock = $connection-> createCommand('UNLOCK TABLES');
In Yii2, you can lock/unlock a table like this
$db = Yii::$app->getDb();
$db ->createCommand('LOCK TABLES `YOUR_TABLE` WRITE')->execute();
// access YOUR_TABLE here
// something like YOUR_TABLE_MODEL::find()->where(["something" => "blah"])->one()
$db ->createCommand('UNLOCK TABLES')->execute();

Updating a column with 1 updates it with 2

I'm a bit confused. I have a website with a sort of user-profiles. When a visitor hits a user-page I want to update the number of views by a date and userid. But, no matter what i do, the number of views is updated with 2 instead of one. I've created an query-output for all queries which are executed during a page-request. The update-query is correct and there's only 1 update-query executed during the page-request.
This is my data-structure:
CREATE TABLE `ProfileView` (
`Id` int(8) NOT NULL auto_increment,
`UserId` int(8) NOT NULL,
`Date` date NOT NULL,
`Views` int(8) NOT NULL,
PRIMARY KEY (`Id`),
KEY `UserId` (`UserId`,`Date`)
) ENGINE=MyISAM AUTO_INCREMENT=10 DEFAULT CHARSET=latin1;
No matter what I do, the column 'Views' is always updated by 2 instead of 1.
The logic being executed (called from a controller, controller gets called from the view. Decorator is basically a sealed stdClass providing strict coding guidance because misspelled properties result in a PropertyDoesntExistException):
Workflow:
# user-details.php
$oControllerProfileView = new Controller_ProfileView();
$oControllerProfileView->Replace($iUserId);
---
# Controller.ProfileView.php
public function Replace($iUserId) {
// validation
Model_ProfileView::Replace($iUserId, date('Y-m-d'));
}
---
# Model.ProfileView.php
static public function Replace($iUserId, $sDate) {
$oData = MySQL::SelectOne("
SELECT Views
FROM ProfileView
WHERE UserId = ".$iUserId."
AND Date = '".$sDate."'");
if(is_a($oData, 'Decorator')) {
MySQL::Query("
UPDATE ProfileView
SET `Views` = ".($oData->Views + 1)."
WHERE UserId = ".$iUserId."
AND Date = '".$sDate."'");
} else {
MySQL::Query("
INSERT INTO ProfileView
VALUES (
NULL,
".$iUserId.",
'".$sDate."',
1
)");
}
}

Codeigniter Datamapper automated created updated fields

Seems like this should be the easy part, but I can't seem to get this going. My created and updated fields are not being populated. I've tried renaming the fields to something different, but no go. Other than the schema and setting up the class (very basic) as below, am I missing something?
Codeigniter v2.1.2
Datamapper ORM v1.8.2.1
Schema:
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`created` datetime NOT NULL,
`updated` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1
User Class:
<?php
class User extends DataMapper
{
function User()
{
parent::DataMapper();
}
}
Ok, found the answer and hopefully this will help someone out. I needed to set the following in the application/config/datamapper.php file:
$config['local_time'] = TRUE;
$config['unix_timestamp'] = FALSE;
$config['timestamp_format'] = 'Y-m-d H:i:s';
In your config/datamapper.php file ensure 'created_field' and 'updated_field' are set to match your DB columns. Or you can override them in the model itself. ie.
<?php
class User extends DataMapper
{
var $created_field = 'created';
var $updated_field = 'updated';
function User()
{
parent::DataMapper();
}
}

Categories