Typo3 MM-relation
by Nox on Apr.02, 2013, under PHP
Recently I had a problem with a typo3 plugin.
I needed to connect some clients with a category and the internet failed me.
TL;DR: The steps to do are:
- Connect 2 models in the extension builder with a n:m relation and save
- Open one of the relations with your editor and change it by using the other relations table and adding 'MM_opposite_field' => 'fieldname' to the configuration
- Create a new Model
- Name it "Client" and set the aggregate root flag to have it build the model data
- Create another Model
- Name it "Category" and set the aggregate root flag
- Now add a relation to Client and name it "categories", connect it to the Category-model
- Add a relation to Category and name it "clients", connect it to the Client-model
- Save the extension
- Open Configuration/TCA/Client.php to see:
'foreign_table' => 'tx_kssclient_domain_model_category',
'MM' => 'tx_kssclient_client_category_mm', - Open Configuration/TCA/Category.php to see:
'foreign_table' => 'tx_kssclient_domain_model_client',
'MM' => 'tx_kssclient_category_client_mm', - These lines need to be changed to look like this:
'foreign_table' => 'tx_kssclient_domain_model_client',
'MM' => 'tx_kssclient_client_category_mm',
'MM_opposite_field' => 'categories', - The generated code was creating to separate n:m-relations. The changed line will turn the category-client n:m-relation into a client-category m:n-relation, which in turn creates the desired m:m relation
Firefox 3.6.13 crash mit localStorage.removeItem
by Nox on Feb.16, 2011, under JavaScript
Probleme mit folgendem Code:
-
jQuery(function($) {
-
$(window).bind('storage', function(_){
-
// Verfy the Storage-Interface
-
if(window.localStorage instanceof Storage)
-
window.localStorage.length // Line is needed, somehow
-
});
-
-
// Not sure if this is needed,
-
// but we should have an A before removing it
-
window.localStorage.setItem('A', JSON.stringify(123));
-
-
// Crash FF!
-
window.localStorage.removeItem('A');
-
});
Wie in Zeile 1 zu sehen, es wird eine aktuellere jQuery Version gebraucht. Aktuellere weil ich es nicht mit älteren probiert habe. Geladen ist momentan diese hier: jQuery 1.5.0
Getestet ist es ausserdem nur im aktuellen Firefox 3.6.13.
Was passiert:
Es wird ein Element aus dem localStorage entfernt und, nachdem das passiert ist, versucht der GarbageCollector irgendwie einen Pointer auf das Element zu nutzen. Das schlägt scheinbar fehl, da wir alles schon per Hand gelöscht haben.
Nun stürzt bei mir leider dabei der Firefox ganz ab... Schade
node.js and global objects
by Nox on Jan.10, 2011, under JavaScript, node.js
Today I had a little problem with a node.js app.
I tried to seperate some parts of the app to different files. The problem that I ran into was that the app was controlled by a config file which was loaded synchronously and then carried on with the app.
-
var config = lib.extend({
-
name: 'unnamed!',
-
port: 3000,
-
mountpoint: '/ft',
-
timeout: 250,
-
wait: 1500,
-
path: './Data'
-
}, require('./' + config));
Now after seperating the server and client parts of this app into two different files I had no access anymore to the config file without always carrying the config object with everything. This let me to a simple solution.
-
var EventEmitter = require('events').EventEmitter;
-
-
var system = new EventEmitter;
-
-
module.exports = system;
-
var system = require('./system');
-
system.config = config;
-
/* now every other code has access to the config
-
via system.config or through system.on('initialize', function(config) {});
-
*/
-
system.emit('initialize', config);
Oh... and the reason for this junk is... The global-object does not seem to work. I tried global.config = config, and it did not work.
Have fun with this
Nox
Mysql & PHP unserialize
by Nox on Jun.01, 2010, under PHP
Yes, I was a bad boy. I did wrong in creating a simple little table that was meant to be an extension for another Table.
Suppose you have an user-table in your database and want to extend it with various data you dont know yet, just as I did some time ago...
You have your table with an id primary key, and some other fields you know, like name, and password. Now you create another table (user_data) to store any, yes ANY, data. This table has an foreign primary key id, that is of course linked to the user.id field. And now, you get 2 more fields user_data.key and user_data.value. Now your table is like an associative array in php, linked only through your id-field to the user table.
Sounds fun, doesnt it?
$user_data = SELECT * FROM `user_data` WHERE `id`=X
$user_data = array_map(convert_with_unserialize, $user_data);
And now you got all the data you want back in PHP. To insert you will have to serialize the data, and to read it, you will have to unserialize it. It's not hard. Actually it's pretty useful, as long as you don't know your data.
But it is hard as hell to run a specific SELECT on user to select everyone that has a white rabbit shoulder tatoo. This data is of course saved in the user_data table as not everyone needs to have a tatoo field.
As you see, you will have to serialize your "question" in some way too. It would be better to write something like this.
This has some other uses, and actually I used it to correct my mistake in creating such a table in the first place. But for any of you, using some kind of serialized data, this function might help.
BEGIN DECLARE len INT DEFAULT LENGTH(str); DECLARE pos INT DEFAULT 0; IF ISNULL(str) THEN RETURN NULL; END IF; IF LEFT(str, 1) = 's' THEN SET pos = LOCATE(':', str, 3) + 2; RETURN MID(str, pos, len - pos - 1); END IF; IF LEFT(str, 1) = 'a' THEN RETURN str; END IF; RETURN MID(str, 3, len - 3); END
It checks for null first, then unserializes strings, then returns arrays as themselfs and then guesses that there are only numbers left. Of course everything is still returned as string, but PHP should do the rest of the dirty work.
Have fun
jQuery IE window.resize fix
by Nox on Nov.05, 2008, under JavaScript
Ich habe mich vor einigen Tagen mal wieder mit dem Internet Explorer herumgeschlagen. Anders als der Firefox triggert dieser das resize-Event nämlich während der Mausbewegung, und nicht erst wenn es abgeschlossen ist.
Dies bedeutet für eine AJAX Anwendung die das resize-Event abfängt Performanzprobleme, denn diese wird nun andauernd getriggert.
Da ich derzeit viel mit jQuery arbeite habe ich mir die Mühe gemacht einen Fix dafür zu schreiben.
if(jQuery.browser.msie) (function ($) {
var bind = jQuery.fn.bind;
jQuery.fn.bind = function( type, data, fn ) {
if(type != "resize")
return bind.apply(this, [type, data, fn]);
var timer = 1;
var args = null;
var handler = function(e, y) {
timer = 1;
(fn || data).apply(this, args);
};
bind.apply(this, [type, data, function() {
if (timer) clearTimeout(timer);
args = arguments;
timer = setTimeout(handler, 150);
}]);
return this;
}
})(jQuery);
Was das Skript macht, es überschreibt im Falle das jQuery einen MS-IE findet. Es wird das alte bind abgespeichert und mit einer extra Funktion aufgerufen die erst bis 150 zählt bevor es das Event weiterleitet, sollte es zu früh getriggert werden dann fängt die Funktion wieder von vorne an zu zählen.
Problem gelöst.