Das Kohana Twitter API Modul macht es einem sehr einfach Twitter in seine Applikationen einzubeziehen.
Archiv für die Kategorie ‘Frameworks’
kohana twitter api modul
Montag, 14. Juni 2010 von sägefischAgavi Custom Logger implementieren
Freitag, 07. Mai 2010 von sägefischUm in Agavi custom logfiles zu erstellen, benötigt man einen eigens erstellten logger + appender in der app/config/logger.xml.
<!-- logs only custom messages in a custom log -->
<logger name="custom" class="AgaviLogger" level="'custom'">
<appenders>
<appender>CustomLogAppender</appender>
</appenders>
</logger>
<appender name="CustomLogAppender" class="AgaviFileLoggerAppender" layout="DateTimeLayout">
<ae:parameters>
<ae:parameter name="file">%core.app_dir%/log/custom.log</ae:parameter>
</ae:parameters>
</appender>
Dann kann man den Logger quasi überall wo der LoggerManager verfügbar ist benutzen.
$message = 'Custom logging message'; $this->getContext()->getLoggerManager()->log(new AgaviLoggerMessage($message, 'custom'), 'custom');
Und in der bash das logfile einsehen.
tail -f app/log/custom.log
Agavi routing specials
Montag, 03. Mai 2010 von sägefischUm bestimmte Agavi output_types bei speziellen routings zu bedienen kann man die routing.xml wie folgt anpassen.
<!-- cut out leading slash -->
<route name="slasher" pattern="^/" stop="false" imply="true" cut="true" />
<!-- match ajax calls with special http header -->
<route pattern="XMLHttpRequest" source="_SERVER[HTTP_X_REQUESTED_WITH]" stop="false" output_type="ajax" />
<!-- match json calls with special http header -->
<route pattern="application/json" source="_SERVER[HTTP_ACCEPT]" stop="false" output_type="json" />
<!-- cut out special pointer -->
<route name="portal" pattern="^({portal:[a-zA-Z]{3}}/)?" stop="false" imply="true" cut="true">
<callbacks>
<callback class="RoutingCallback" />
</callbacks>
</route>
PDF Dokumente mit Zend LiveDocx
Montag, 30. November 2009 von sägefischEin sehr interessanter Ansatz zur Erzeugung von Dokumenten im Web wird bei phphatesme.com beschrieben. HTML-zu-PDF-Konvertierung und programmatischer Ansatz sind ja bekannt. Der neue Ansatz bedient sich einer SOAP Schnittstelle und Templates. Unter folgender URL gibts mehr dazu:
Eigene Configs in Agavi nutzen
Dienstag, 10. November 2009 von grasteFür diverse Aufgaben in größeren Projekten ist es notwendig, eigene XML-Konfigurationsdateien zu nutzen. Die Definition umfangreicher Einstellungen in der settings.xml wird schnell anstrengend und das Holen der Werte per AgaviConfig::get('setting.name', 'default'); unübersichtlich. Agavi bietet es aber an, eigene Konfigurationsdateien zu erstellen und diese nicht nur zu validieren, sondern auch zur Wiederverwendung zu cachen.
In der Agavi FAQ habe ich dazu mal ein Beispiel verfasst.
Einfach einen Config-Handler in der config_handlers.xml definieren:
<handler pattern="%core.config_dir%/project/foo/*.xml" class="AgaviReturnArrayConfigHandler" />
und dann direkt in den Actions, Views und Models benutzen:
if (!isset($config['baz']))
{
throw new LogicException('baz is missing!');
}
if (isset($config['bars']))
{
foreach ($config['bars'] as $foo => $data)
{
$this->doSomethingWithEach($foo, $data);
}
}
Die XML-Datei für den obigen Code könnte beispielweise so aussehen:
<ae:configurations>
<ae:configuration>
<baz>asdf</baz>
<foo>-1</foo>
<bars>
<some>...more data and xml...</some>
<more>...more data and xml...</more>
<deep>...more data and xml...</deep>
<structs>...more data and xml...</structs>
</bars>
</ae:configuration>
<ae:configuration environment="production.*">
<baz>bleh</baz>
<foo>1</foo>
</ae:configuration>
</ae:configurations>
Gut zu erkennen ist der Vorteil eigener Configs: Man kann die Agavi-Features für Konfigurationsdateien nutzen und auf einfache Art und Weise environmentspezifische Einstellungen vornehmen (z.B. in “Production” andere Werte für Logdateien, URLs oder Einstellungen nutzen als während der Entwicklung oder beim Testen).
Ebenfalls gut zu erkennen im PHP-Code ist, dass man lauter Abfragen über die Existenz bestimmer Elemente macht, die man sich mit vernünftiger Validierung sparen kann, da invalide XML-Dokumente gar nicht erst als korrekt angesehen werden von Agavi. Um seine XML-Strukturen zu validieren definiert man per validation Parameter ein XML-Schema und definiert noch gleich einen eigenen ConfigHandler, den man schreibt und per autoload.xml bekannt macht:
<handler pattern="%core.config_dir%/project/foo/*.foo.xml" class="FooDefinitionConfigHandler">
<validation>%core.config_dir%/xsd/foo_definition.xsd</validation/>
</handler>
Der ConfigHandler könnte so beginnen:
class FooDefinitionConfigHandler extends AgaviXmlConfigHandler
{
// notwendige Methoden implementieren und XML-Struktur validieren...
}
Für Beispiele einfach in die in Agavi verwendeten XSDs und entsprechende ConfigHandler sehen. Viel Spaß. :)
der Kohana Script Collector Helper
Sonntag, 25. Oktober 2009 von sägefischUm modular und agil in Kohana zu entwickeln, wurde ein Skript Kollektor notwendig, der aus allen Controllern (Template- oder Standard-Controllern) Skripte (CSS, Javascript) sammeln kann.
Diese Scripte werden dann auf den jeweiligen Mastertemplates wieder an den richtigen Stellen eingebunden.
Dazu habe ich einen neuen Helper unter application/helpers/collector.php eingerichtet.
class Collector_Core
{
/**
* Arrays containing URL's to scripts/styles (fill with standards)
* @var string
*/
static protected $scripts = array();
static protected $styles = array();
/**
* Adds a url to store
* @param string $file the local path to file
* @return void
*/
static public function addJs($file)
{
self::$scripts[] = $file;
}
/**
* Adds a url to store
* @param string $file the local path to file
* @return void
*/
static public function addCss($file)
{
self::$styles[] = $file;
}
/**
* Generates/renders collectors items
* @param boolean $print whether to echo the output or just return rendered string
* @return string the rendered output
*/
static public function renderJs($print = false)
{
$scripts = array_unique(self::$scripts);
$output = html::script($scripts);
if ($print)
{
echo $output;
}
else
{
return $output;
}
}
/**
* Generates/renders collectors items
* @param boolean $print whether to echo the output or just return rendered string
* @param string|array $media type for this style (all, screen, print, media)
* @return string the rendered output
*/
static public function renderCss($print = false, $media = 'all')
{
$styles = array_unique(self::$styles);
$output = html::stylesheet($styles, $media);
if ($print)
{
echo $output;
}
else
{
return $output;
}
}
} // end of Collector_Core
Dieser Helper kann nun aus allen Controllern heraus befüllt werden.
class Welcome_Controller extends Template_Controller
{
/**
* set master template
*/
public $template = 'master_default.tpl';
/**
* default constructor
* @param void
* @return void
*/
public function __construct()
{
// load parent constructor
parent::__construct();
// collect scripts and styles
collector::addCss('/css/fancybox');
collector::addJs('/js/jquery.1.3.2');
collector::addJs('/js/jquery.fancybox');
}
/** more code here */
} // end of Welcome_Controller
Nachdem nun alle relevanten Skripte eingesammelt wurden, kann man diese auf dem Template wieder ausgeben lassen.
<?php collector::renderCss(true, 'all'); ?> <!-- html code here --> <?php collector::renderJs(true); ?>
Der Kollektor sorgt dafür das keine doppelten Skripte geladen werden.
die inoffizielle Agavi FAQ
Sonntag, 25. Oktober 2009 von sägefischAllen die immernoch sehnsüchtig auf eine offizielle Agavi Doku warten, sei hier die inoffizielle FAQ Variante von mivesto ans Herz gelegt.
Agavi auf XAMPP und Windows
Sonntag, 25. Oktober 2009 von sägefischNachdem ich das offizielle Agavi DOC durchforstet habe und keine Lösung für meine Testumgebung fand, stieß ich auf diesen Link hier:
simonholywell.com/article/installing-agavi-on-xampp-windows
Herr Holywell selbst hat eine prima Einführung in die Installation von Agavi auf XAMPP und Windows geliefert.
Hier der Post im Original:
Having recently heard of the Agavi project from a web framework showdown at a PHP conference in the UK I have decided to trial it. My setup is a WinXP computer with a default install of the latest XAMPP which has thrown up some issues with installing and building Agavi. Please see my hints below to overcome these issues.
1. Open a command prompt (type cmd in the run console)
2. Navigate to your XAMMP PHP directory. Mine is C:\xampp-test\php
3. Execute pear.bat channel-discover pear.agavi.org
4. Execute pear.bat install agavi/agavi
Agavi is now installed! Now we just need a new default project to work from.
Agavi needs to be told where the phing batch file is stored.
1. Edit the agavi.bat file in the XAMPP php directory. Mine is C:\xampp-test\php\agavi.bat
2. Change set PHING_COMMAND=phing to contain the full absolute path to phing.bat which is in the XAMPP php folder. Mine looks like this: set PHING_COMMAND=C:\xampp-test\php\phing.bat
Begin setting up your project directory.
1. Create a new directory in your XAMPP directory. Mine is C:xampp-testhtdocssimonholywell.com
2. Create an empty text file called build.properties in the directory (this banishes a build error where phing fails if it cannot find the file)
3. Open a command prompt and navigate to the new directory
4. Execute agavi.bat project The agavi.bat file is stored in the XAMPP php folder. My command looked like this: C:\xampp-test\php\agavi.bat project
5. Follow the prompts the installer gives you (hitting enter will supply the installer with the [default] value)
Agavi should now be setup for your project. View it in your browser to verify.
SOAP Service mit Kohana und Zend AutoDiscover
Sonntag, 25. Oktober 2009 von sägefischEine einfache all-in-one Lösung für Standard SOAP Services kann man mit dem Kohana Framework und der Zend Bibliothek realisieren.
Dazu bedarf es lediglich eines Kohana Frontcontrollers über den wir den Service und die WSDL ansprechen können.
Zur automatischen Generierung der WSDL, bedienen wir uns hier der Zend AutoDiscover Klasse. Dieser Klasse übergibt man lediglich die ServiceModel-Klasse mit enthaltenen Annotationen, die die Servicefunktionen enthält.
Aus den Annotationen generiert Zend AutoDiscover eine passende WSDL.
/**
* include libs and models
*
*/
include('Zend/Soap/AutoDiscover.php');
include(APPPATH . 'models/service.php');
/**
* this class represents a controller
* application/controllers/soap.php
*
* @package SOAPService
* @subpackage ...
* @author saegefisch (xxx@xxx.xx)
* @copyright (c) 2009 xxx
*/
class Soap_Controller extends Controller
{
/**
* default constructor
*
* @param void
* @return void
*/
public function __construct()
{
// load parent constructor
parent::__construct();
}
/**
* service to call
*
* @param void
* @return void
*/
public function service()
{
// disable wsdl cache
ini_set('soap.wsdl_cache_enabled', '0');
// set auth settings if needed
$settings = array(
'login' => 'user',
'password' => 'password',
'authentication' => SOAP_AUTHENTICATION_BASIC,
'soap_version' => SOAP_1_2,
'encoding' => 'UTF-8',
'cache_wsdl' => WSDL_CACHE_NONE
);
// include user:password if needed
$wsdl = 'http://user:password@' . $_SERVER['HTTP_HOST'] . '/soap/wsdl';
$server = new SoapServer($wsdl, $settings);
$server->setClass('Service_Model');
$server->handle();
}
/**
* wsdl to call
*
* @param void
* @return void
*/
public function wsdl()
{
// disable wsdl cache
ini_set('soap.wsdl_cache_enabled', '0');
$wsdl = new Zend_Soap_AutoDiscover();
$wsdl->setUri('http://' . $_SERVER['HTTP_HOST'] . '/soap/service');
$wsdl->setClass('Service_Model');
$wsdl->handle();
}
}
Hier stellen wir das Standard Model für unseren SOAP Service zusammen.
/**
* this class represents a model
* application/models/service.php
*
* @package SOAPService
* @subpackage ...
* @author saegefisch (xxx@xxx.xx)
* @copyright (c) 2009
*/
class Service_Model extends Model
{
/**
* default constructor
*
* @param void
* @return void
*/
public function __construct()
{
// load database library into $this->db (can be omitted if not required)
parent::__construct();
}
/**
* dummy function
*
* @param int $int
* @param string $string
* @param array $arr
* @param object $obj
* @param bool $bool
* @return array
*/
public function get_dummy_array($int, $string, $arr, $obj, $bool)
{
return array();
}
/**
* dummy function
*
* @param int $int
* @param string $string
* @param array $arr
* @param object $obj
* @param bool $bool
* @return bool
*/
public function get_dummy_boolean($int, $string, $arr, $obj, $bool)
{
return true;
}
/**
* dummy function
*
* @param int $int
* @param string $string
* @param array $arr
* @param object $obj
* @param bool $bool
* @return string
*/
public function get_dummy_string($int, $string, $arr, $obj, $bool)
{
return 'foo=bar';
}
}


















