kodal.de

it´s all about music, design and coding

Archive for the ‘ coding ’ Category

Im Magento-Backend (1.4) gibt es keine Möglichkeit, einmal erstellte Rechnungen wieder zu löschen. Um eine einzelne Rechnung zu eliminieren, ist dieser MySQL-Query hilfreich:

delete from `sales_order_entity_datetime` where `entity_id`='$entityId' and `entity_type_id` IN (17,18,19);
delete from `sales_order_entity_decimal` where `entity_id`='$entityId' and `entity_type_id` IN (17,18,19);
delete from `sales_order_entity_int` where `entity_id`='$entityId' and `entity_type_id` IN (17,18,19);
delete from `sales_order_entity_text` where `entity_id`='$entityId' and `entity_type_id` IN (17,18,19);
delete from `sales_order_entity_varchar` where `entity_id`='$entityId' and `entity_type_id` IN (17,18,19);
delete from `sales_order_entity` where `parent_id`='$entityId' and `entity_type_id`='20';
delete from `sales_order_entity` where `entity_id`='$entityId' and `entity_type_id`='18';

Dahinter verbirgt sich folgende Logik:

"sales_order_entity_*":
delete from `$table` where `entity_id`='$entityId' and `entity_type_id` IN (17,18,19);

"sales_order_entity":
delete from `$table` where `parent_id`='$entityId' and `entity_type_id`='20';
delete from `$table` where `entity_id`='$entityId' and `entity_type_id`='18';

Popularity: 18% [?]

Leider gibt es in Magento keine Möglichkeit, einmal erstelle Orders wieder zu löschen. Was aus buchhalterischer Sicht durchaus sinnvoll sein mag, erweist sich in der Praxis oftmals als Stolperfalle. Denn insbesondere in der Entwicklungsphase eines eCommerce-Projekts kommt man um das testweise Anlegen von Bestellungen kaum herum, um die Abrechnungs- und Fulfillment-Funktionalität von Magento und eventuell zusätzlich installierter Extensions auf Herz und Nieren zu prüfen.

Diese Bestellungen und Rechnungen liegen, wenn sie erst einmal erstellt worden sind, in der Datenbank vor, obwohl sie nie für die weitere Bearbeitung vorgesehen waren. Das ist besonders ärgerlich bei Bestellungen, die nur testweise angelegt wurden, um zB die Funktionalität des Shops oder einzelner Extensions zu überprüfen. Werden diese Testorders zB versehentlich bei der Erfassung des Steueraufkommens im Zuge der Umsatzermittlung mitberücksichtigt, ist Ärger vorprogrammiert.

Derartige Testorders, aber natürlich auch alle übrigen Bestellungen und Rechnungen, können zwar nicht über das Magento-Backend direkt, wohl aber über einen SQL-Inject gelöscht werden.
Für Magento 1.4.1 sieht diese SQL-Anweisung wie folgt aus:


SET FOREIGN_KEY_CHECKS=0;

TRUNCATE `sales_order`;
TRUNCATE `sales_order_datetime`;
TRUNCATE `sales_order_decimal`;
TRUNCATE `sales_order_entity`;
TRUNCATE `sales_order_entity_datetime`;
TRUNCATE `sales_order_entity_decimal`;
TRUNCATE `sales_order_entity_int`;
TRUNCATE `sales_order_entity_text`;
TRUNCATE `sales_order_entity_varchar`;
TRUNCATE `sales_order_int`;
TRUNCATE `sales_order_text`;
TRUNCATE `sales_order_varchar`;
TRUNCATE `sales_flat_quote`;
TRUNCATE `sales_flat_quote_address`;
TRUNCATE `sales_flat_quote_address_item`;
TRUNCATE `sales_flat_quote_item`;
TRUNCATE `sales_flat_quote_item_option`;
TRUNCATE `sales_flat_order_item`;
TRUNCATE `sendfriend_log`;
TRUNCATE `tag`;
TRUNCATE `tag_relation`;
TRUNCATE `tag_summary`;
TRUNCATE `wishlist`;
TRUNCATE `log_quote`;
TRUNCATE `report_event`;

ALTER TABLE `sales_order` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_datetime` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_decimal` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_datetime` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_decimal` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_int` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_text` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_entity_varchar` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_int` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_text` AUTO_INCREMENT=1;
ALTER TABLE `sales_order_varchar` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_address` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_address_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_item` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_quote_item_option` AUTO_INCREMENT=1;
ALTER TABLE `sales_flat_order_item` AUTO_INCREMENT=1;
ALTER TABLE `sendfriend_log` AUTO_INCREMENT=1;
ALTER TABLE `tag` AUTO_INCREMENT=1;
ALTER TABLE `tag_relation` AUTO_INCREMENT=1;
ALTER TABLE `tag_summary` AUTO_INCREMENT=1;
ALTER TABLE `wishlist` AUTO_INCREMENT=1;
ALTER TABLE `log_quote` AUTO_INCREMENT=1;
ALTER TABLE `report_event` AUTO_INCREMENT=1;

-- reset customers
TRUNCATE `customer_address_entity`;
TRUNCATE `customer_address_entity_datetime`;
TRUNCATE `customer_address_entity_decimal`;
TRUNCATE `customer_address_entity_int`;
TRUNCATE `customer_address_entity_text`;
TRUNCATE `customer_address_entity_varchar`;
TRUNCATE `customer_entity`;
TRUNCATE `customer_entity_datetime`;
TRUNCATE `customer_entity_decimal`;
TRUNCATE `customer_entity_int`;
TRUNCATE `customer_entity_text`;
TRUNCATE `customer_entity_varchar`;
TRUNCATE `log_customer`;
TRUNCATE `log_visitor`;
TRUNCATE `log_visitor_info`;

ALTER TABLE `customer_address_entity` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_datetime` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_decimal` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_int` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_text` AUTO_INCREMENT=1;
ALTER TABLE `customer_address_entity_varchar` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_datetime` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_decimal` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_int` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_text` AUTO_INCREMENT=1;
ALTER TABLE `customer_entity_varchar` AUTO_INCREMENT=1;
ALTER TABLE `log_customer` AUTO_INCREMENT=1;
ALTER TABLE `log_visitor` AUTO_INCREMENT=1;
ALTER TABLE `log_visitor_info` AUTO_INCREMENT=1;

-- Reset all ID counters
TRUNCATE `eav_entity_store`;
ALTER TABLE `eav_entity_store` AUTO_INCREMENT=1;

SET FOREIGN_KEY_CHECKS=1;

Popularity: 20% [?]

Unlike in ActionScript2, we cannot use a MovieClip´s or Sprites´ z-Property to arrange objects on the z-axis. However, the new ActionScript3-handling provides a solution which comes in even handier..

Bring object to front

function moveUpfront( clip:DisplayObject ):void {
    clip.parent.setChildIndex(clip, clip.parent.numChildren-1);
}

Send object to back

function moveToBack( clip:DisplayObject ):void {
    clip.parent.setChildIndex(clip, 0);
}

Move one up

function moveForward( clip:DisplayObject ): void {
   var currentDepth = clip.parent.getChildIndex(clip);
   if(currentDepth<clip.parent.numChildren-1){
      clip.parent.setChildIndex(clip, currentDepth+1);
   }
}

Move one down

function moveBackward( clip:DisplayObject ): void {
   var currentDepth = clip.parent.getChildIndex(clip);
   if(currentDepth>0){
      clip.parent.setChildIndex(clip, currentDepth-1);
   }
}

Popularity: 31% [?]

Problems with Product Visibility in Magento

When first setting up a Magento-eCommerce-site, almost everyone wonders why products are not being shown on the actual site, even though everything seems to be filled out correctly. In this little article, I’d like to explain how to make sure a product is shown on the site after it has been created via the Magento-backend.

Here goes a little checklist of what to do in order to have your products being shown in your Magento-eCommerce-Shop..

Checklist

  • in Catalog/Manage Products : fil out all required fields in each tab and click “save and continue edit” when finished
  • in Catalog/Manage Products/General : make sure “Status” is set to “Enabled”
  • in Catalog/Manage Products/General : set “Visibility” to “Catalog”, “Search” or “Catalog, Search”
  • in Catalog/Manage Products/Inventory : set “Qty” to a value greater than 0
  • in Catalog/Manage Products/Inventory : set “Stock Availability” to “In Stock”
  • in Catalog/Catgories : assign your product to at least one category (you might have to create one first)
  • in CMS/Pages : select “Home Page”, then switch to the “Content”-tab and enter {{block type=”catalog/product_list” category_id=”21″ template=”catalog/product/list.phtml”}} into the large content-textarea (you might have to adjust the category_id if your newly created category_id differs from the one in this example.

Popularity: 35% [?]

Customizing Magento by overwriting core-classes

There are several possibilities of overwriting single magento-methods or whole classes. Of course you could be just altering the core-classes themselves in a quick and dirty approach. however, you should avoid this practice under all circumstances, because it corrupts the update-facilities of your eCommerce-site. Once you are upgrading your magento-copy to a newer version, all your changes would get lost.

Luckily, overwriting native magento-classes is pretty straight-forward, and therefore there is no reason not to do it the right way.

In this example, we are overwriting the core method of the block-class “Onepage_Billing” of the Mage_Checkout-core module to add another default address. This is just an example to show how you actually add new functionality by inheriting from a Magento-coreclass and overwriting particular methods.

Extend Magento Core-Class

app/code/local/Test/Checkout/Block/Onepage/Billing.php

First we derive from the class that we actually want to overrule. In our example, we are simply overwriting the core Onepage_Billing-class of the Mage_Checkout-core-module with an inherited class called

Test_Checkout_Block_Onepage_Billing

, which declares and therfore overrules the method

getAddressesHtmlSelect

. In this method we can add and/or alter all the functionality that we actually need.

<?php
class Test_Checkout_Block_Onepage_Billing extends Mage_Checkout_Block_Onepage_Billing
{
    public function getAddressesHtmlSelect($type)
    {
        if ($this->isCustomerLoggedIn()) {
            $options = array();
            foreach ($this->getCustomer()->getAddresses() as $address) {
                $options[] = array(
                    'value' => $address->getId(),
                    'label' => $address->format('oneline')
                );
            }

            $addressId = $this->getAddress()->getCustomerAddressId();
            if (empty($addressId)) {
                if ($type=='billing') {
                    $address = $this->getCustomer()->getPrimaryBillingAddress();
                } else {
                    $address = $this->getCustomer()->getPrimaryShippingAddress();
                }
                if ($address) {
                    $addressId = $address->getId();
                }
            }

            $select = $this->getLayout()->createBlock('core/html_select')
                ->setName($type.'_address_id')
                ->setId($type.'-address-select')
                ->setClass('address-select')
                ->setExtraParams('onchange="'.$type.'.newAddress(!this.value)"')
                ->setValue($addressId)
                ->setOptions($options);

            return $select->getHtml();
        }
        return '';
    }
}

Activate Module

app/etc/modules/Test_All.xml

Now it’s time to tell Magento that there is a module (in our example we have named it “Test”) which adds customized functionality to the Magento-core-functionality.

<?xml version="1.0"?>
<config>
    <!-- Please add items in alphabetic order. -->
    <modules>
        <Test_Checkout>
            <active>true</active>
            <codePool>local</codePool>
        </Test_Checkout>
     </modules>
</config>

Actual Overwrite

app/code/local/Test/Checkout/etc/config.xml

Now this is where the Magento-rewrite-magic pops in. By providing a rewrite-directive in the Test_Checkout-config.xml, Magento’s default behaviour can be overruled for certain pages, and we can make sure that our derived class is being loaded instead of the core Checkout-module from Magento.

<?xml version="1.0"?>
<config>
    <modules>
         <Test_Checkout>
            <version>0.1.0</version>
        </Test_Checkout>
    </modules>
    <global>
	    <blocks>
		    <checkout>
		        <rewrite>
		            <onepage_billing>Test_Checkout_Block_Onepage_Billing</onepage_billing>
		        </rewrite>
		    </checkout>
		</blocks>
   </global>
</config>

Clear Cache

Whenever we are changing Magento-settings by adding or modifying the underlying xml-configuration-files, we have to empty the cache (residing at app/var/cache) in order to have the changes come into effect. So before going wild because your changes don’t show, rather empty Magento’s file-cache.

Popularity: 83% [?]

Das Problem:
Wenn ein dynamisches Textfeld auf der obersten Ebene einer Schaltfläche liegt, erscheint beim Darüberfahren mit der Maus nicht wie beim Rest der Schaltfläche der Hand-Cursor, sondern der normale Mauszeiger, auch wenn die akive Fläche des Buttons weiterhin bestehen bleibt.

Im Klartext: Ein Button mit oben aufliegendem dynamischen Textfeld bleibt klickbar, aber der Mauszeiger wechselt über der betreffenden Textfläche nicht wie gewünscht zum Hand-Cursor.

Abhilfe:
Unter ActionScript 2 beheben wir dieses Phänomen, indem wir das “selectable”-Attribut des betreffenden Textfeldes auf false setzen. Die Möglichkeit, den Inhalt eines Textfeldes auszuwählen, steht nämlich bei AS2 in Konkurrenz zu den MouseEvents, die bei auswählbaren Textfeldern unter AS2 nicht an die dahinter liegende aktive Fläche eines Buttons weitergereicht (und somit ausgewertet) werden können.

Unter AS2 hilft uns diese Anweisung, um den Mauszeigerwechsel auch über Textfeldern zu bewirken:

Textfeld.selectable = false;

Dies hilft uns allerdings unter ActionScript3 nicht weiter. Auch wenn ein Textfeld nicht auswählbar ist, fängt es trotzdem etwaige MouseEvents ab, die dann nicht mehr für darunterliegende Schaltflächen zur Verfügung stehen.

Wir schaffen für dieses Problem Abhilfe, indem wir das “mouseEnabled”-Attribut heranziehen, das seit AS3 auch für alle Textfelder bereitsteht. Wenn wir mit Hilfe von

Textfeld.mouseEnabled = false;

verhindern, dass das Textfeld selbst auf Mausevents reagiert, halten wir so gleichzeitig auch den “Luftraum” über der aktiven Schaltfläche frei. Anschließend wird nicht mehr das Textfeld, sondern wie gewünscht die dahinterliegende Schaltfläche für MouseEvents empfänglich..

Popularity: 81% [?]

Smarty – Tips

February 10, 2010 Smarty, coding, php Comments

Find some tricks on how to use Smarty effectively here.

Array handling in Smarty

Arrays are a bit tricky to handle in Smarty. But only at first glance! If you know your way around, it´s pretty easy to cope with them. Note that you can use virtually every native php-function by using modifiers, which allow you to use smarty as a smart wrapper for all php-functions:

array_push

let´s say you want to push the value “new” to an existing array named $offers. You can simply do so by using this term:

{$offers|@array_push:"new"}

Note the @-identifier, which makes smarty process the given array as a whole, rather than iterating through each element of the array.

This approach has a disadvantage, though. After having executed array_push, the returning result will be piped to smarty and therefore we have an unwanted output of the function´s result.

We can simply avoid this by following this approach:

{assign var="void" value=$offers|@array_push:"new"}

By doing so, we are assigning the return value from array_push to a variable (named “void”). As a result, the return-value is being stored in a variable rather than leading to an unwanted output of the latter.

in_array

if you want to check whether a the given value “new” exists within a given $offers, try this:

{"new"|in_array:$offers}

Popularity: 29% [?]

I am willing to grant you a first little insight into my actionscript (AS3) poison cabinet today. ;)

/* ----------------------------------------------------- */
/* coding: timor kodal [pulsar-network]					 */
/* copyright by: (c) 2010 timor kodal				     */
/* ----------------------------------------------------- */
/* contact: [http://pulsar.cc | timor [at] kodal.de      */
/* ----------------------------------------------------- */
/* to see this and other scripts in action, please visit */
/* http://pulsar.cc										 */
/* ----------------------------------------------------- */
/* you are free to use my scripts 					     */
/* according to the creative commons licence cc-nc-by    */
/* ----------------------------------------------------- */
/* more information: http://creativecommons.org          */
/* ----------------------------------------------------- */

package pflash.widget
{
	import flash.display.*;
	import flash.events.Event;
	import flash.geom.*;
	import flash.text.TextField;
	import flash.text.TextFormat;

	public class Flowchart extends MovieClip {

		public var data : Object;
		public var graph : Array;
		public var range : Object;
		public var colors : Array;

		public var captionDuration = 400;
		public var captionPosition : String = "final";

		public var mcGrid : MovieClip;
		public var mcStats : MovieClip;

		public var w : Number = 200;
		public var h : Number = 80;

		public var invertX : Boolean = false;
		public var invertY : Boolean = true;

		public var dateX : Boolean = false;
		public var dateY : Boolean = false;

		public var intervalX : Number = 5;
		public var intervalY : Number = 5;
		public var highlightX : Number = 4;
		public var highlightY : Number = 4;
		public var meterX : Number = 1;
		public var meterY : Number = 1;

		public var textFormat : TextFormat = null;

		/* CONSTRUCTOR */
		public function Flowchart (data = false) {
			this.data = new Object();
			this.graph = new Array();
			this.range = new Object();
			this.colors = new Array();
			this.colors['default'] = [uint(0xff8888),uint(0x44ff44)];
			this.colors['gridX'] = uint(0x888888);
			this.colors['gridY'] = uint(0x888888);
			this.colors['meterX'] = uint(0x444444);
			this.colors['meterY'] = uint(0x444444);

			if (data)
				this.importArray(data);
		}
		public function createGradient(colors,alphas:Array = null,ratios:Array = null):Object {
			var gradient = new Object();
			gradient.colors = colors;
			if (alphas)
				gradient.alphas = alphas;
			else
				gradient.alphas = [0.6,0.2];
			if (ratios)
				gradient.ratios = ratios;
			else
				gradient.ratios = [0x00,0xff];
			return gradient;
		}

		private function drawStats (): Sprite {
			var stats = new Sprite();
			var dots = new Sprite();
			stats.addChild(dots);
			var realx;
			var point:Point;
			var nextPoint:Point;
			var color;
			var x1,x2,y1,y2: Number;
			var first = new Array();
			var last = new Array();
			var typecount = 0;
			var that = this;
			for (var type in this.graph) {
				if (this.colors[type]) {
					color = this.colors[type];
				} else if (typeof this.colors['default']=="number") {
					color = this.colors['default'];
				} else if (this.colors['default'][typecount%this.colors['default'].length]) {
					color = this.colors['default'][typecount%this.colors['default'].length];
				}
				var label = new MovieClip();
				if (typeof(color)=="object") {
					stats.graphics.lineStyle(2,color.colors[0],0.8);
					dots.graphics.lineStyle(2,color.colors[0],1);
					label.graphics.beginFill(this.colors[type].colors[0]);
					if (!color.matrix) {
						color.matrix = new Matrix();
						color.matrix.createGradientBox(this.h,80,Math.PI / 2,10,0);
					}
					stats.graphics.beginGradientFill(GradientType.LINEAR, color.colors, color.alphas, color.ratios, color.matrix, SpreadMethod.PAD);
				} else {
					stats.graphics.lineStyle(2,color,0.8);
					dots.graphics.lineStyle(2,color,1);
	 			    stats.graphics.beginFill(color,0.4);
					label.graphics.beginFill(color,0.8);
				}
				for (var x in this.graph[type]) {
					point = this.graph[type][x];
					x1 = (point.x-this.range.minx)/(this.range.maxx-this.range.minx)*this.w;
					if (this.invertX)
						x1 = this.w-x1;
					y1 = (point.y-this.range.miny)/(this.range.maxy-this.range.miny)*this.h;
					if (this.invertY)
						y1 = this.h-y1;
					if (!first[type]) {
						first[type] = new Point(x1,y1);
						stats.graphics.moveTo(x1,y1);
					}
					stats.graphics.lineTo(x1,y1);
					dots.graphics.drawCircle(x1,y1,1);
					if (this.graph[type][x+1]) {
						nextPoint = this.graph[type][x+1];
						trace(Math.floor(x1)+"x"+Math.floor(y1)+":"+Math.floor(x2)+"x"+Math.floor(y2));
					} else {
						nextPoint = new Point(point.x,this.range.miny);

						if (that.captionDuration!=="permanent") {
							label.addEventListener(Event.ENTER_FRAME,labelView);
							var count = 0;
							function labelView(e: Event) {
								count++;
								if (count>that.captionDuration)
									e.target.alpha/=1.1;
							}
						}

						var textfield = new TextField();
						textfield.htmlText = "<font face='Helvetica,Verdana,Arial' color='#000000' size='7px'>"+type+"</font>";
						textfield.selectable = false;

						label.graphics.drawRect(0, 2, textfield.textWidth+3,textfield.textHeight);
						label.graphics.endFill();

						if (this.captionPosition=="final") {
							label.y=y1-5;
							label.x=x1+5;
						} else {
							label.y=0+typecount*(textfield.textHeight+1);
							label.x=this.w+5;
						}

						if (label.x+textfield.textWidth>this.w-10)
							label.x-=textfield.textWidth+12;

						label.addChild(textfield);

						label.alpha=0.8;
						stats.addChild(label);

					}
					x2 = (nextPoint.x-this.range.minx)/(this.range.maxx-this.range.minx)*this.w;
					if (this.invertX)
						x2 = this.w-x2;
					y2 = (nextPoint.y-this.range.miny)/(this.range.maxy-this.range.miny)*this.h;
					if (this.invertY)
						y2 = this.h-y2;
					stats.graphics.lineTo(x2,y2);
					last[type]=new Point(x2,y2);
				}
				stats.graphics.lineTo(last[type].x,this.h);
				stats.graphics.lineTo(first[type].x,this.h);
				stats.graphics.endFill();
				typecount++;
			}
			return stats;
		}
		private function drawGrid (data = false): Sprite {
			if (data)
				this.importArray(data);
			var grid = new Sprite();
			var labels = new MovieClip();
			if (this.intervalX<2)
				this.intervalX=2;
			if (this.intervalY<2)
				this.intervalY=2;
			var realx;
			var realy;
			for (var x=0;x<=this.w;x+=this.intervalX) {
				realx = x;
				if (!this.invertX)
					realx = this.w-x;
				if (realx/this.intervalX%this.highlightX==0) {
					grid.graphics.lineStyle(1,this.colors['gridX']);

					var num = Math.floor((this.w-x)/this.w*(this.range.maxx-this.range.minx)+this.range.minx);
					var tfcontainer = new MovieClip();
					var textfield = new TextField();

					if (this.dateX) {
						var d = new Date(num*1000);
					 	num = Number(d.getMonth()+1)+" "+d.getFullYear();
					}

					if (this.textFormat) {
						textfield.defaultTextFormat = this.textFormat;
						textfield.embedFonts = true;
						textfield.text = num;
						textfield.rotation=90;
					} else {
						textfield.htmlText = "<font family='Helvetica, Verdana, Arial' size='7px' color='#ffffff'>"+num+"</font>";
					}

					//textfield.text = num;
					textfield.selectable = false;
					tfcontainer.addChild(textfield);
					tfcontainer.y=this.h;
					tfcontainer.x=realx+textfield.textHeight/2+2;

					labels.addChild(tfcontainer);
				} else
					grid.graphics.lineStyle(1,this.colors['gridX'],0.5);
				grid.graphics.moveTo(realx,0);
				grid.graphics.lineTo(realx,this.h);
			}
			for (var y=0;y<=this.h;y+=this.intervalY) {
				realy = y;
				if (this.invertY)
					realy = this.h-y;
				if (realy/this.intervalY%this.highlightY==0) {
					grid.graphics.lineStyle(1,this.colors['gridY']);

					var num = Math.floor(y/this.h*(this.range.maxy-this.range.miny)+this.range.miny);
					var textfield = new TextField();

					if (this.dateY) {
						var d = new Date(num*1000);
					 	num = Number(d.getMonth()+1)+" "+d.getFullYear();
					}

					if (this.textFormat) {
						textfield.defaultTextFormat = this.textFormat;
						textfield.embedFonts = true;
						textfield.text = num;
					} else {
						textfield.htmlText = "<font face='Arial' family='Helvetica, Verdana, Arial' size='7px' color='#ffffff'>"+num+"</font>";
					}

					textfield.selectable = false;
					textfield.y=realy-textfield.textHeight/2-2;
					textfield.x=this.w+2;

					labels.addChild(textfield);
				} else
					grid.graphics.lineStyle(1,this.colors['gridY'],0.5);

				grid.graphics.moveTo(0,realy);
				grid.graphics.lineTo(this.w,realy);
			}
			grid.addChild(labels);
			grid.alpha=0.5;
			return grid;
		}
		public function draw (data = false) {
			if (data)
				this.importArray(data);

			var mc = new MovieClip();
			mc.addChild(this.drawGrid());
			mc.addChild(this.drawStats());

			mc.x=0;
			mc.y=0;

			this.addChild(mc);
		}
		public function importArray (data) {
			this.data = data;
			this.graph = new Array();
			var buf;
			var y; /* y-value */
			var x; /* x-value */
			var t; /* type */
			var point:Point;

			for(var t in this.data) {
				if (!this.graph[t])
					this.graph[t] = new Array();

				var keys : Array = [];
				for( var key : String in this.data[t] ) keys.push( key );
				keys.sort();

				for(var key in keys) {
					x=keys[key];
					y=this.data[t][x];
					this.graph[t].push(new Point(x,y));
					if (!this.range.hasOwnProperty('minx') || x<this.range['minx'])
						this.range.minx=Number(x);
					if (!this.range.hasOwnProperty('maxx') || x>this.range['maxx'])
						this.range.maxx=Number(x);
					if (!this.range.hasOwnProperty('miny') || y<this.range['miny'])
						this.range.miny=Number(y);
					if (!this.range.hasOwnProperty('maxy') || y>this.range['maxy'])
						this.range.maxy=Number(y);
					trace("statistics ("+this.graph[t].length+"): "+t+" :"+x+"/"+y);

				}
			}
			trace(this.range.minx+" "+this.range.maxx+"/"+this.range.miny+" "+this.range.maxy);

		}

		public function importObjects (data) {
			this.data = data;
			this.graph = new Array();
			var buf;
			var y; /* y-value */
			var x; /* x-value */
			var t; /* type */
			var point:Point;

			for(var t in this.data) {
				if (!this.graph[t])
					this.graph[t] = new Array();

				for(var key in this.data[t]) {
					x=this.data[t][key].x;
					y=this.data[t][key].y;
					this.graph[t].push(new Point(x,y));
					if (!this.range.hasOwnProperty('minx') || x<this.range['minx'])
						this.range.minx=Number(x);
					if (!this.range.hasOwnProperty('maxx') || x>this.range['maxx'])
						this.range.maxx=Number(x);
					if (!this.range.hasOwnProperty('miny') || y<this.range['miny'])
						this.range.miny=Number(y);
					if (!this.range.hasOwnProperty('maxy') || y>this.range['maxy'])
						this.range.maxy=Number(y);
					trace("statistics ("+this.graph[t].length+"): "+t+" :"+x+"/"+y);

				}
			}
			trace(this.range.minx+" "+this.range.maxx+"/"+this.range.miny+" "+this.range.maxy);

		}

	}

}

Example:



feel free to download the flowchart-widget

Popularity: 100% [?]

Seit dem Jahreswechsel ist auf der non-kommerziellen Netaudioplattform Pulsar ( http://pulsar.cc ) ein selbstentwickelter (Netaudio)Mp3-Player integriert, der auf ActionScript3 basiert, und nach langer Flash-Abstinenz auch gleichzeitig meine erste Flash-Entwicklung nach fast 5 Jahren darstellt.

Since New Year´s, you can find an embedded (netaudio)-mp3-player on my netlabel Pulsar ( http://pulsar.cc ). After more than 5 years pause from developing flash-projects, this is also my first actionscript3-tool I have built.

Popularity: 26% [?]

Using PHP for shell-scripting

January 30, 2010 coding, php Comments

This class is a first step to a comprehensive, and yet handy little collection of helper-functions, which can ease your way along while using php for shell-scripts.

Whereas most of you probably use php as a scripting-language for websites, it´s also a very good alternative to other shell-scripting languages like perl or python. In fact, I find it a lot more useful than regular shell-scripts.

This little class can be used both as a static collection of shell-methods, but you can also create instances of it.

So far, it automatically parses any userparams coming from the commandline, and stores them in a publicly available array named self::$arguments.

More features are to be added soon :)

<?
	/* ----------------------------------------------------- */
	/* coding: timor kodal [pulsar-network]					 */
	/* copyright by: (c) 2010 timor kodal				     */
	/* ----------------------------------------------------- */
	/* contact: [http://pulsar.cc | timor [at] kodal.de      */
	/* ----------------------------------------------------- */
	/* to see this and other scripts in action, please visit */
	/* http://pulsar.cc										 */
	/* ----------------------------------------------------- */
	/* you are free to use my scripts 					     */
	/* according to the creative commons licence cc-nc-by    */
	/* ----------------------------------------------------- */
	/* more information: http://creativecommons.org          */
	/* ----------------------------------------------------- */

     class shell {
		public $arguments;
		public $defaults;
		public $aliases;
		function __construct (Array $args = NULL,Array $aliases = NULL,Array $defaults = NULL) {
			$this->aliases = $aliases;
			$this->defaults = $defaults;
			$this->arguments = self::parseArguments($args,$aliases,$defaults);
		}
		public function getArgs(Array $defaults = NULL) {
			$args = $this->arguments;
			if ($defaults) {
				foreach ($defaults as $k=>$v) {
					if (!isset($args[$k]))
						$args[$k]=$v;
					if (!isset($args[$this->aliases[$k]]) && $this->aliases[$k])
						$args[$this->aliases[$k]]=$v;
				}
			}
			return $args;
		}
		public static function parseArguments (Array $args = NULL, Array $aliases = NULL,Array $defaults = NULL) {
			global $argv;
			if (!$aliases)
				$aliases = Array ("u"=>"user");
			if (!$args)
				$args=$argv;

			$arguments = Array();
			$count = 0;

			// -u=1
			// -u test
			// --user=1
			if (is_array($defaults)) {
				foreach ($defaults as $k=>$v) {
					$arguments[$k]=$v;
					if ($aliases[$k])
						$arguments[$aliases[$k]]=$v;
				}
			}

			foreach ($args as $k=>$v) {
				$pattern = "/\-{1,2}([a-z]+)=(.*)/";
				preg_match($pattern,$v,$matches);
				if ($matches[0]) {
					$arguments[$matches[1]]=$matches[2];
					if ($aliases[$matches[1]])
						$arguments[$aliases[$matches[1]]]=$matches[2];
				} else
					$arguments[]=$v;
			}
			return $arguments;
		}
	}

?>

download class.shell.php

Example:

<?
 require_once("class.shell.php");
 $aliases = Array("u"=>"uid","d"=>"default");

 $shell = new shell(NULL,$aliases,Array("u"=>"root"));

 print_r($shell->getArgs(Array("d"=>"yes")));

// php5 example.shell.php -user=teamore

// output:

// Array
// (
// [u] => root
// [uid] => root
// [0] => initprocmail.php
// [user] => teamore
// [d] => yes
// [default] => yes
// )

?>

download example.shell.php

Popularity: 22% [?]