Can't get data just saved in database in Laravel 5.1 - laravel-5.1

I successfully save data in the database. However, the data can't be found after saving.
In the JSON,the key object's value is an empty array.
My database schema:
CREATE TABLE IF NOT EXISTS `bigdata_db`.`objects` (
`object_id` CHAR(34) NOT NULL,
`object_lt_x` FLOAT NOT NULL,
`object_lt_y` FLOAT NOT NULL,
`object_width` FLOAT NOT NULL,
`object_height` FLOAT NOT NULL,
`image_id` CHAR(34) NOT NULL,
`type_id` CHAR(34) NOT NULL,
PRIMARY KEY (`object_id`),
INDEX `fk_objects_images1_idx` (`image_id` ASC),
INDEX `fk_objects_types1_idx` (`type_id` ASC),
CONSTRAINT `fk_objects_images1`
FOREIGN KEY (`image_id`)
REFERENCES `bigdata_db`.`images` (`image_id`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `fk_objects_types1`
FOREIGN KEY (`type_id`)
REFERENCES `bigdata_db`.`types` (`type_id`)
ON DELETE CASCADE
ON UPDATE CASCADE);
My object model:
protected $table = 'objects';
public $timestamps = false;
protected $primaryKey = 'object_id';
public $incrementing = false;
protected $fillable = ['object_id','object_lt_x', 'object_lt_y', 'object_width', 'object_height', 'image_id', 'type_id'];
Save the data to database
$obj = new Object;
$obj->object_id = $objectId;
$obj->object_lt_x = $objX;
$obj->object_lt_y = $objY;
$obj->object_width = $objWidth;
$obj->object_height = $objHeight;
$obj->image_id = $imageId;
$obj->type_id = $typeId;
if ($obj->save()) {
$obj_id = $obj->object_id;
$object = DB::table('objects')->where('object_id',$objectId)->get();
$success = array('status' => 1,'message' => $type_name.'标记成功!','obj_id' => $obj_id,'object' => $object);
return response()->json($success);
} else {
$error = array('status' => 0,'message' => $type_name.'标记失败!');
return response()->json($error);
}
The result is:
Object {status: 1, message: "眼睛标记成功!", obj_id: "A7313004-3B7D-56F2-602F-FC81D4A8F04F", object: Array[0]}

Looks to me that you have a conditional for $obj->save() but you never actually called $obj->save(); to save the Entry.
$obj = new Object;
$obj->object_id = $objectId;
$obj->object_lt_x = $objX;
$obj->object_lt_y = $objY;
$obj->object_width = $objWidth;
$obj->object_height = $objHeight;
$obj->image_id = $imageId;
$obj->type_id = $typeId;
$obj->save();
if ($obj->save()) {
$obj_id = $obj->object_id;
$object = DB::table('objects')->where('object_id',$objectId)->get();
$success = array('status' => 1,'message' => $type_name.'标记成功!','obj_id' => $obj_id,'object' => $object);
return response()->json($success);
} else {
$error = array('status' => 0,'message' => $type_name.'标记失败!');
return response()->json($error);
}

Related

Open prepopulated SQLite data base in react-native, where to put database?

I am following instructions on importing existing db to my App
(for IOS):https://www.npmjs.com/package/react-native-sqlite
Have created www folder in myProject directory, put there myDataBase.
Added folder to xcode.
this is my src code to open it and make a query :
import SQLite from 'react-native-sqlite-storage'
function errorCB(err) {
console.log("SQL Error: " + err);
}
function successCB() {
console.log("SQL executed fine");
}
function openCB() {
console.log("Database OPENED");
}
console.log('database.js')
var db = null;
export function openDB() {
// var db = SQLite.openDatabase("test.db", "1.0", "Test Database", 200000, openCB, errorCB);
db = SQLite.openDatabase({name : "words", createFromLocation : 1}, openCB,errorCB);
}
export function getWord(str) {
db.transaction((tx) => {
tx.executeSql("SELECT * FROM words", [], (tx, results) => {
console.log("Query completed");
// Get rows with Web SQL Database spec compliance.
var len = results.rows.length;
console.log('len' + len)
for (let i = 0; i < len; i++) {
let row = results.rows.item(i);
console.log(`word: ${row.str}, Dept Name: ${row.smth}`);
}
// Alternatively, you can use the non-standard raw method.
/*
let rows = results.rows.raw(); // shallow copy of rows Array
rows.map(row => console.log(`Employee name: ${row.name}, Dept Name: ${row.deptName}`));
*/
});
});
}
I am getting:
Built path to pre-populated DB asset from app bundle www subdirectory: /Users/mac/Library/Developer/CoreSimulator/Devices/06420F74-0E1C-47C1-BCAC-5D3574577349/data/Containers/Bundle/Application/75EE8E9A-276F-402F-982A-DBF30DE80802/MyApp.app/www/words
RCTLog.js:48 target database location: nosync
RCTLog.js:48 Opening db in mode READ_WRITE, full path: /Users/mac/Library/Developer/CoreSimulator/Devices/06420F74-0E1C-47C1-BCAC-5D3574577349/data/Containers/Data/Application/67D2451F-3D72-4B82-AC90-AD6DB9A82566/Library/LocalDatabase/words
Database opened
RCTLog.js:48 Good news: SQLite is thread safe!
dataBase.js:13 Database OPENED
RCTLog.js:48 open cb finished ok
sqlite.core.js:475 Error handler not provided: {message: "no such table: words", code: 5}
sqlite.core.js:572 warning - exception while invoking a callback: {"code":5}
Don't know what is the reason of this error?
I have checked in DB browser for SQLite that DB is correct and table 'words' exists in it and have rows in it.
I have tried different names for db file: 'words', 'words.db', 'words.sqlite' nothing helps.
I am running my app from console as :
react-native run-ios
SQLite.openDatabase({name:"testDB.sqlite3", createFromLocation:1,location:'Library'})
This solved my problem. testDB.sqlite3 file size is 24 MB.
testDB.sqlite and testDB.db not working, but testDB.sqlite3 is working.
Here I build a Repository, hop it help you
import BaseModule from '../baseModule';
import * as SQLite from 'expo-sqlite';
import * as MediaLibrary from 'expo-media-library';
import * as FileSystem from 'expo-file-system';
import * as Permissions from 'expo-permissions';
import DetaliItemsSettings from '../detaliItemSettings';
import ChapterSettings from '../chapterSettings';
import httpClient from '../http';
export type NovelReaderSettingsType = (items: BaseModule) => void;
export type Find = (foundItems: BaseModule[]) => void;
export default class Repository {
static dbIni: Boolean;
databaseName: string;
constructor() {
this.databaseName = 'test.db';
}
importSettings = async (uri: string) => {
try {
const {status} = await Permissions.askAsync(Permissions.MEDIA_LIBRARY);
if (status === 'granted') {
var json = await FileSystem.readAsStringAsync(uri, {encoding: 'utf8'});
if (json) console.log(json);
var item = JSON.parse(json) as {
applicationSettings: any;
items: DetaliItemsSettings[];
};
var appSettings = await this.where('ApplicationSettings');
if (item.applicationSettings) {
item.applicationSettings = httpClient.cloneItem(
appSettings.length > 0 ? appSettings[0] : {},
item.applicationSettings,
['id', 'tableName'],
);
await this.save(
item.applicationSettings,
undefined,
'ApplicationSettings',
);
}
if (item.items && item.items.length > 0) {
for (var i = 0; i < item.items.length; i++) {
var a = item.items[i];
var b = (await this.where('DetaliItems', {
novel: a.novel,
})) as DetaliItemsSettings[];
var aChapterSettings =
a.chapterSettings ?? ([] as ChapterSettings[]);
var bChaptersSettings =
b && b.length > 0
? ((await this.where('Chapters', {
detaliItem_Id: b[0].id,
})) as ChapterSettings[])
: ([] as ChapterSettings[]);
var updatedChapterSettings = [] as ChapterSettings[];
if (b && b.length > 0) {
if (a.chapterIndex) b[0].chapterIndex = a.chapterIndex;
b[0].isFavorit = true;
a = b[0];
}
aChapterSettings.forEach((x) => {
var bCh = bChaptersSettings.find(
(a) => a.chapterUrl === x.chapterUrl,
);
if (bCh)
updatedChapterSettings.push(
httpClient.cloneItem(bCh, x, ['id', 'tableName']),
);
else updatedChapterSettings.push(x);
});
let detaliItemSettings = await this.save(
a,
undefined,
'DetaliItems',
);
for (var y = 0; y <= aChapterSettings.length - 1; y++) {
let m = aChapterSettings[y];
m.detaliItem_Id = detaliItemSettings.id;
await this.save(m, undefined, 'Chapters');
}
}
}
return true;
}
} catch (error) {
console.log(error);
}
return false;
};
exportFileToDownloadFolder = async () => {
try {
const {status} = await Permissions.askAsync(Permissions.MEDIA_LIBRARY);
if (status === 'granted') {
var favoriteData = (await this.where('DetaliItems', {
isFavorit: true,
})) as DetaliItemsSettings[];
for (var i = 0; i < favoriteData.length; i++) {
var item = favoriteData[i];
item.chapterSettings = (await this.where('Chapters', {
detaliItem_Id: item.id,
})) as ChapterSettings[];
item.id = 0;
item.chapterSettings.forEach((x) => {
x.id = 0;
x.detaliItem_Id = 0;
});
}
var result = {
applicationSettings:
(await this.where('ApplicationSettings')).length > 0
? (await this.where('ApplicationSettings'))[0]
: undefined,
items: favoriteData,
};
let fileUri = FileSystem.documentDirectory + 'NovelManager.db';
await FileSystem.writeAsStringAsync(fileUri, JSON.stringify(result), {
encoding: FileSystem.EncodingType.UTF8,
});
const asset = await MediaLibrary.createAssetAsync(fileUri);
await MediaLibrary.createAlbumAsync('Download', asset, false);
return true;
}
} catch (error) {
console.log(error);
}
return false;
};
dataBasePath = () => {
return FileSystem.documentDirectory + this.databaseName;
};
createConnection = () => {
return SQLite.openDatabase(this.databaseName);
};
allowedKeys = (tableName: string) => {
return new Promise((resolve, reject) => {
this.createConnection().transaction(
(x) =>
x.executeSql(
`PRAGMA table_info(${tableName})`,
undefined,
(trans, data) => {
var keys = [] as string[];
for (var i = 0; i < data.rows.length; i++) {
if (data.rows.item(i).name != 'id')
keys.push(data.rows.item(i).name);
}
resolve(keys);
},
),
(error) => {
reject(error);
},
);
}) as Promise<string[]>;
};
selectLastRecord = async (item: BaseModule) => {
console.log('Executing SelectLastRecord...');
return (
await this.find(
item.id <= 0
? `SELECT * FROM ${item.tableName} ORDER BY id DESC LIMIT 1;`
: `SELECT * FROM ${item.tableName} WHERE id=?;`,
item.id > 0 ? [item.id] : undefined,
)
).map((x) => {
x.tableName = item.tableName;
return x;
});
};
delete = async (item: BaseModule, tableName?: string) => {
tableName = item.tableName ?? tableName;
var q = `DELETE FROM ${tableName} WHERE id=?`;
await this.execute(q, [item.id]);
};
public save = (
item: BaseModule,
insertOnly?: Boolean,
tableName?: string,
) => {
if (!item.tableName) item.tableName = tableName ?? '';
return new Promise(async (resolve, reject) => {
try {
await this.setUpDataBase();
console.log('Executing Save...');
var items = await this.where(item.tableName, {id: item.id});
var keys = (await this.allowedKeys(item.tableName)).filter((x) =>
Object.keys(item).includes(x),
);
let query = '';
let args = [] as any[];
if (items.length > 0) {
if (insertOnly) return;
query = `UPDATE ${item.tableName} SET `;
keys.forEach((k, i) => {
query += ` ${k}=? ` + (i < keys.length - 1 ? ',' : '');
});
query += ' WHERE id=?';
} else {
query = `INSERT INTO ${item.tableName} (`;
keys.forEach((k, i) => {
query += k + (i < keys.length - 1 ? ',' : '');
});
query += ') values(';
keys.forEach((k, i) => {
query += '?' + (i < keys.length - 1 ? ',' : '');
});
query += ')';
}
keys.forEach((k: string, i) => {
args.push(item[k] ?? null);
});
if (items.length > 0) args.push(item.id);
await this.execute(query, args);
resolve((await this.selectLastRecord(item))[0]);
} catch (error) {
console.log(error);
reject(error);
}
}) as Promise<BaseModule>;
};
public find = (query: string, args?: any[]) => {
return new Promise((resolve, reject) => {
this.createConnection().transaction(
async (x) => {
await this.setUpDataBase();
console.log('Executing Find..');
x.executeSql(
query,
args,
async (trans, data) => {
console.log('query executed:' + query);
var items = [] as BaseModule[];
for (var i = 0; i < data.rows.length; i++) {
var t = data.rows.item(i);
items.push(t);
}
resolve(items);
},
(_ts, error) => {
console.log('Could not execute query:' + query);
console.log(error);
reject(error);
return false;
},
);
},
(error) => {
console.log(error);
reject(error);
},
);
}) as Promise<BaseModule[]>;
};
where = async (tableName: string, query?: any) => {
var q = `SELECT * FROM ${tableName} ${query ? 'WHERE ' : ''}`;
var values = [] as any[];
if (query) {
Object.keys(query).forEach((x, i) => {
q += x + '=? ' + (i < Object.keys(query).length - 1 ? 'AND ' : '');
values.push(query[x]);
});
}
return (await this.find(q, values)).map((x) => {
x.tableName = tableName;
return x;
});
};
findOne = async (tableName: string, query?: any) => {
var items = await this.where(tableName, query);
return items && items.length > 0 ? items[0] : undefined;
};
execute = async (query: string, args?: any[]) => {
return new Promise((resolve, reject) => {
this.createConnection().transaction(
(tx) => {
console.log('Execute Query:' + query);
tx.executeSql(
query,
args,
(tx, results) => {
console.log('Statment has been executed....' + query);
resolve(true);
},
(_ts, error) => {
console.log('Could not execute query');
console.log(args);
console.log(error);
reject(error);
return false;
},
);
},
(error) => {
console.log('db executing statement, has been termineted');
console.log(args);
console.log(error);
reject(error);
throw 'db executing statement, has been termineted';
},
);
});
};
public dropTables = async () => {
await this.execute(`DROP TABLE if exists ApplicationSettings`);
await this.execute(`DROP TABLE if exists DetaliItems`);
await this.execute(`DROP TABLE if exists Chapters`);
Repository.dbIni = false;
await this.setUpDataBase();
};
setUpDataBase = async () => {
let applicationSetupQuery = `CREATE TABLE if not exists ApplicationSettings (
id INTEGER NOT NULL UNIQUE,
backGroundColor TEXT NOT NULL,
fontSize INTEGER NOT NULL,
lineHeight INTEGER NOT NULL,
fontFamily TEXT NOT NULL,
marginLeft INTEGER NOT NULL,
marginRight INTEGER NOT NULL,
detaliItem_Id INTEGER,
selectedParserIndex INTEGER,
PRIMARY KEY(id AUTOINCREMENT)
);`;
let detaliItemsQuery = `CREATE TABLE if not exists DetaliItems (
image TEXT NOT NULL,
title TEXT NOT NULL,
description TEXT NOT NULL,
novel TEXT NOT NULL,
parserName TEXT NOT NULL,
chapterIndex INTEGER NOT NULL,
id INTEGER NOT NULL,
isFavorit INTEGER NOT NULL,
PRIMARY KEY(id AUTOINCREMENT)
);`;
let chapterQuery = `CREATE TABLE if not exists Chapters (
id INTEGER NOT NULL UNIQUE,
chapterUrl TEXT NOT NULL,
isViewed INTEGER NOT NULL,
currentProgress NUMERIC NOT NULL,
finished INTEGER NOT NULL,
detaliItem_Id INTEGER NOT NULL,
PRIMARY KEY(id AUTOINCREMENT),
CONSTRAINT "fk_detaliItem_id" FOREIGN KEY(detaliItem_Id) REFERENCES DetaliItems(id)
);`;
if (!Repository.dbIni) {
console.log('dbIni= false, setUpDataBase');
await this.execute(applicationSetupQuery);
await this.execute(detaliItemsQuery);
await this.execute(chapterQuery);
Repository.dbIni = true;
} else {
console.log('dbIni= true, setUpDataBase');
}
};
}

which URL pattern is better, action/id or id/action

I would like to know which of these 2 patterns would be better:
/photos/123/edit
or
/photos/edit/123
Currently I am using the first, which gives me a Whoops, looks like something went wrong. when I try /photos/123/editxx instead of a 404 not found.
routes:
I am unsure where to look for the mistake, these are the photos routes:
Route::get('photos/randpics','PhotosController#randpics');
Route::get('photos/{id}/edit','PhotosController#getEdit')->middleware(['auth']);
Route::post('photos/{id}/edit','PhotosController#postEdit')->middleware(['auth']);
Route::post('photos/{id}/retag', ['as' => 'photos.retag', 'uses' => 'PhotosController#retag'])->middleware(['auth']);
Route::post('photos/{id}/delete','PhotosController#delete')->middleware(['auth']);
Route::get('photos/{id}/albums', 'PhotosController#getAlbums')->middleware(['auth']);
Route::post('photos/{id}/albums', 'PhotosController#postAlbums')->middleware(['auth']);
Route::get('photos/{id}/detail','PhotosController#detail');
Route::get('photos/{id}','PhotosController#single');
Route::post('photos/like', 'PhotosController#postLike')->middleware(['auth']);
Route::post('photos/unlike', 'PhotosController#postUnlike')->middleware(['auth']);
Route::get('photos','PhotosController#index');
getEdit() and postEdit():
The same error, complaining about an undefined variable in the master layout template appears, when I enter /photos/123/a/a/a/ for example.
public function getEdit(Request $request, $id = null)
{
$pic = Pic::findOrFail($id);
if(Gate::denies('edit-pic',$pic)) {
abort(403);
}
$pic->text = htmlspecialchars($pic->text);
$years = array_combine(range(date("Y"), 1960), range(date("Y"), 1960));
$location = $pic->location;
$tags = $pic->tags;
$tagsarray = $pic->tagNames();
$albums = $pic->albums;
$locations = array();
$getlocations = Location::orderBy('city')->get();
foreach($getlocations as $gl)
{
$locations[$gl->id] = $gl->city.' ('.$gl->country.')';
}
$cats = Cat::lists('cat','cat')->all();
return view('photos.edit',compact('pic','location','tags','tagsarray','albums','locations','cats','years'));
}
public function postEdit(Request $request, $id = null)
{
$pic = Pic::findOrFail($id);
if(Gate::denies('edit-pic',$pic)) {
abort(403);
}
$this->validate($request, [
'title' => 'max:200',
'text' => 'max:3000',
'location' => 'required|exists:locations,id',
'cat' => 'required|exists:cats,cat',
'jahrprod' => 'date_format:Y'
]);
$pic->title = trim($request->input('title'));
$pic->text = trim($request->input('text'));
$pic->jahrprod = ($request->input('jahrprod')) ? $request->input('jahrprod') : null;
$pic->location_id = $request->input('location');
$pic->cat = $request->input('cat');
$pic->save();
#mail
$maildata = array(
'msg' => 'picture '.$id.' ( '.$request->input('title').' ) was edited by '.Auth::user()->username
);
Mail::send(['text' => 'emails.empty'], $maildata, function($message){
$message->to('xx#yy.de')->from('xx#yy.de')->subject('picture edited');
});
return back()->with('success','photo information updated');
}
Controller.php
It seems, with more than 2 URL segments, the Controller.php is not working properly. /domain.xy/1/2 shows the 8 but /domain.xy/1/2/3 throws the error Undefined variable: photos_online
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Auth;
use Cache;
use DB;
use App\Pic;
use App\Upload;
use Carbon\Carbon;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
public function __construct()
{
dd(8);
//.......
}
}
If you follow laravel's resource controller guidelines
https://laravel.com/docs/5.2/controllers#restful-resource-controllers
You should go with the first one.
But to fix your problem show us your route and controller function handling it.
Update
open AppServiceProvider located in app/http/providers
and replace boot() function with this
public function boot()
{
//initilizw $photos_online
$photos_online = Cache::rememberForever('index_countpics', function()
{
return Pic::count();
});
#pics today
if (Cache::has('pics_today')){
$pics_today = Cache::get('pics_today');
}else{
$pics_today = Pic::whereRaw('DATE(created_at) = DATE(NOW())')->count();
Cache::put('pics_today', $pics_today, Carbon::tomorrow());
}
# count waiting uploads
$waiting_uploads = Cache::rememberForever('waiting_uploads', function()
{
return Upload::where('accepted',0)->where('infos',1)->count();
});
# user online
$client_ip = request()->ip();
$check = DB::table('useronline')->where('ip', $client_ip)->first();
$username = (Auth::guest()) ? null : Auth::user()->username;
$displayname = (Auth::guest()) ? null : Auth::user()->displayname;
if(is_null($check)){
DB::table('useronline')->insert(['ip' => $client_ip, 'datum' => DB::raw('NOW()'), 'username' => $username, 'displayname' => $displayname]);
}else{
DB::table('useronline')->where('ip', $client_ip)->update(['datum' => DB::raw('NOW()'), 'username' => $username, 'displayname' => $displayname]);
}
DB::delete('DELETE FROM useronline WHERE DATE_SUB(NOW(), INTERVAL 3 MINUTE) > datum');
$users_online = DB::table('useronline')->whereNotNull('username')->get();
$guests_online = DB::table('useronline')->count();
#unread messages
$unread_messages = 0;
if(Auth::check()){
$unread_messages = Auth::user()->newThreadsCount();
}
view()->share('photos_online',$photos_online);
view()->share('pics_today',$pics_today);
view()->share('waiting_uploads',$waiting_uploads);
view()->share('users_online',$users_online);
view()->share('guests_online',$guests_online);
view()->share('unread_messages',$unread_messages);
}

How to validate input array with a same name in laravel controller

I have a problem when a i try to insert record into table like this .
$data = array();
foreach($input['user_id'] as $key => $user_id) {
$data[$key]['user_id'] = $user_id;
}
foreach($input['start_on'] as $key => $start_on) {
$data[$key]['start_on'] = $start_on;
}
$this->validate($request, [
'time_start' => 'required|date',
'time_end' => 'required|date|after:time_start',
]);
$rules = [
'start_on' => 'required|date|after:time_start|before:time_end|different:start_on'
];
// Iterate and validate each question
foreach ($data as $value)
{
$validator = Validator::make( $value, $rules );
// if ($validator->fails()) return $validator->messages()->all();
}
I want to check start_on not equals another start_on.So what can i do?

zend2 mysql - joining table using TableGateway

I want to aquire data from two mySql tables:
SELECT L.id AS 'l_id', L.date, L.action, U.id AS 'u_id', U.name, U.surname
FROM cases_log L, users U
WHERE L.user = U.id
LIMIT 0,30
So, I've decided to use $select->join, but it doesn't work in way I want. It has aqured data only from cases_log table.
SELECT *
FROM `cases_log`
JOIN users
ON users.id = cases_log.user
Module.php:
'HistoryTable' => function($sm)
{
$tableGateway = $sm->get('HistoryTableGateway');
$table = new HistoryTable($tableGateway);
return $table;
},
'HistoryTableGateway' => function ($sm)
{
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new History());
return new TableGateway('cases_log', $dbAdapter, null, $resultSetPrototype);
},
HistoryTable.php:
$table = $this->tableGateway;
$select = $table->getSql()->select();
//$select->from(array('L' => 'cases_log'))->join(array('U' => 'users'),'L.user = U.id');
$select->join('users', 'users.id = cases_log.user');
$select->limit(10);
$select->offset(0);
$resultSet = $table->selectWith($select);
return $resultSet;
As You can see, in commented line, I've tried to do something in $select->from - but without result, because $select->from is read only ...
I'm new to ZF2 so, I miss somethis maybe?
$table = $this->tableGateway;
$select = $table->getSql()->select();
$select->columns(['l_id' => 'id', 'date', 'action']);
$select->join('users', 'users.id = cases_log.user', ['u_id' => 'id', 'name', 'surname']);
$select->limit(10);
$select->offset(0);
produces the correct sql (except the aliases for the table)

How to hook tags to displayTopColumn in prestashop 1.6

Can somebody tell me how to display tags in TopColumn in prestashop 1.6?
I know that I must edit blogtags.php but I don't know how to do it - my PHP is too weak.
Of course I tried - now can I can hook tag in admin panel but not on website. What have I done?
.
.
.
function install()
{
$success = (parent::install() && $this->registerHook('header') && **$this->registerHook('displayTopColumn')** && Configuration::updateValue('BLOCKTAGS_NBR', 10));
if ($success)
.
.
.
public function hookdisplayTop($params)
{
return $this->hookdisplayTopColumn($params);
}
.
.
.
Full blogtags.php
if (!defined('_PS_VERSION_'))
exit;
define('BLOCKTAGS_MAX_LEVEL', 3);
class BlockTags extends Module
{
function __construct()
{
$this->name = 'blocktags';
$this->tab = 'front_office_features';
$this->version = '1.2.1';
$this->author = 'PrestaShop';
$this->need_instance = 0;
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Tags block');
$this->description = $this->l('Adds a block containing your product tags.');
$this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_);
}
function install()
{
$success = (parent::install() && $this->registerHook('header') && $this->registerHook('displayTopColumn') && Configuration::updateValue('BLOCKTAGS_NBR', 10));
if ($success)
{
// Hook the module either on the left or right column
$theme = new Theme(Context::getContext()->shop->id_theme);
if ((!$theme->default_left_column || !$this->registerHook('leftColumn'))
&& (!$theme->default_right_column || !$this->registerHook('rightColumn'))
&& $this->registerHook('displayTopColumn'))
{
// If there are no colums implemented by the template, throw an error and uninstall the module
$this->_errors[] = $this->l('This module need to be hooked in a column and your theme does not implement one');
parent::uninstall();
return false;
}
}
return $success;
}
public function getContent()
{
$output = '';
if (Tools::isSubmit('submitBlockTags'))
{
if (!($tagsNbr = Tools::getValue('BLOCKTAGS_NBR')) || empty($tagsNbr))
$output .= $this->displayError($this->l('Please complete the "Displayed tags" field.'));
elseif ((int)($tagsNbr) == 0)
$output .= $this->displayError($this->l('Invalid number.'));
else
{
Configuration::updateValue('BLOCKTAGS_NBR', (int)$tagsNbr);
$output .= $this->displayConfirmation($this->l('Settings updated'));
}
}
return $output.$this->renderForm();
}
/**
* Returns module content for left column
*
* #param array $params Parameters
* #return string Content
*
*/
function hookLeftColumn($params)
{
$tags = Tag::getMainTags((int)($params['cookie']->id_lang), (int)(Configuration::get('BLOCKTAGS_NBR')));
$max = -1;
$min = -1;
foreach ($tags as $tag)
{
if ($tag['times'] > $max)
$max = $tag['times'];
if ($tag['times'] < $min || $min == -1)
$min = $tag['times'];
}
if ($min == $max)
$coef = $max;
else
{
$coef = (BLOCKTAGS_MAX_LEVEL - 1) / ($max - $min);
}
if (!sizeof($tags))
return false;
foreach ($tags AS &$tag)
$tag['class'] = 'tag_level'.(int)(($tag['times'] - $min) * $coef + 1);
$this->smarty->assign('tags', $tags);
return $this->display(__FILE__, 'blocktags.tpl');
}
function hookRightColumn($params)
{
return $this->hookLeftColumn($params);
}
function hookHeader($params)
{
$this->context->controller->addCSS(($this->_path).'blocktags.css', 'all');
}
public function hookdisplayTop($params)
{
return $this->hookdisplayTopColumn($params);
}
public function renderForm()
{
$fields_form = array(
'form' => array(
'legend' => array(
'title' => $this->l('Settings'),
'icon' => 'icon-cogs'
),
'input' => array(
array(
'type' => 'text',
'label' => $this->l('Displayed tags'),
'name' => 'BLOCKTAGS_NBR',
'class' => 'fixed-width-xs',
'desc' => $this->l('Set the number of tags you would like to see displayed in this block.')
),
),
'submit' => array(
'title' => $this->l('Save'),
)
),
);
$helper = new HelperForm();
$helper->show_toolbar = false;
$helper->table = $this->table;
$lang = new Language((int)Configuration::get('PS_LANG_DEFAULT'));
$helper->default_form_language = $lang->id;
$helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0;
$helper->identifier = $this->identifier;
$helper->submit_action = 'submitBlockTags';
$helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false).'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->tpl_vars = array(
'fields_value' => $this->getConfigFieldsValues(),
'languages' => $this->context->controller->getLanguages(),
'id_language' => $this->context->language->id
);
return $helper->generateForm(array($fields_form));
}
public function getConfigFieldsValues()
{
return array(
'BLOCKTAGS_NBR' => Tools::getValue('BLOCKTAGS_NBR', Configuration::get('BLOCKTAGS_NBR')),
);
}
}
Change this:
public function hookdisplayTop($params)
{
return $this->hookdisplayTopColumn($params);
}
To that:
public function hookdisplayTopColumn($params)
{
return $this->hookLeftColumn($params);
}

Resources