Demon’s Code

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
I wanted to connect a client-model with a categories-model. So I first created the client model
  • 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
Leave a Comment more...

Firefox 3.6.13 crash mit localStorage.removeItem

by Nox on Feb.16, 2011, under JavaScript

Probleme mit folgendem Code:

  1. jQuery(function($) {
  2.     $(window).bind('storage', function(_){
  3.         // Verfy the Storage-Interface
  4.         if(window.localStorage instanceof Storage)
  5.             window.localStorage.length // Line is needed, somehow
  6.     });
  7.  
  8.     // Not sure if this is needed,
  9.     // but we should have an A before removing it
  10.     window.localStorage.setItem('A', JSON.stringify(123));
  11.  
  12.     // Crash FF!
  13.     window.localStorage.removeItem('A');
  14. });

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

Leave a Comment :, more...

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.

  1. var config = lib.extend({
  2.     name:         'unnamed!',
  3.     port:         3000,
  4.     mountpoint:   '/ft',
  5.     timeout:      250,
  6.     wait:         1500,
  7.     path:         './Data'
  8. }, 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.

  1. var EventEmitter = require('events').EventEmitter;
  2.  
  3. var system = new EventEmitter;
  4.  
  5. module.exports = system;
  1. var system  = require('./system');
  2. system.config = config;
  3. /* now every other code has access to the config
  4.    via system.config or through  system.on('initialize', function(config) {});
  5. */
  6. 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

Leave a Comment : more...

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 = SELECT * FROM `user` WHERE `id`=X
$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.

SELECT `id` FROM `user_data` WHERE `key`='tatoo' AND `value`='s:12:white rabbit';

As you see, you will have to serialize your "question" in some way too. It would be better to write something like this.

SELECT `id` FROM `user_data` WHERE `key`='tatoo' AND UNSERIALIZE(`value`)='white rabbit';

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

Leave a Comment :, more...

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.

Leave a Comment more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Visit our friends!

A few highly recommended friends...

Archives

All entries, chronologically...