Programming / Scripting
Dynamic method calling from applescript
0Applescript comes handy sometimes when you need to do some automation job quick within the MAC OS. Though it lacks many of the features offered by the modern languages, you can sometimes simulate them doing some dirty tricks
. One of them is dynamic calling of the methods of a particular script. let’s take the case where you want for example to store some options for your script in a separate file though it might look like a fancy way of storing options. so it will look something like
--script_options.scpt on AppleOptions() return some options end AppleOptions on GrapesOptions() return some options end GrapesOptions .... on Options() --this should be a default option return some sort of options end Options
Now if the calling of these options depends on some context that changes every time you run your script, you can still call your methods without knowing beforehand what’s going to be called, like this:
--main.scpt
set theFruit to some_value_that_came_from_current_context
set selScpt to path_to_the_options_script_file
set selScpt to load script selScpt
set scptOpt to Options() of selScpt
try
set _scptOpt to run script ("on run (inArgs)" & return & "set theCaller to item 1 of inArgs" & return & "tell (item 1 of inArgs) to " & theFruit & "Options()" & return & "end run") with parameters {selScpt}
--optionally check for empty list or string returned in the try block
end try
if (_scptOpt is not "" and _scptOpt is not {}) then
--display dialog "ok"
set scptOpt to _scptOpt
end if
Calling the above script with theFruit set as “Apple” (no case checking in the above script though) will call your imported script’s AppleOptions() or if not found will get the default Options method.
Removing chosen jquery select box replacement
0$("select").removeClass("chzn-done").css('display', 'inline').data('chosen', null);
$("*[class*=chzn]").remove();
Pin problem with eclipse-php in Windows 7
0Eclipse 3.0.2 tends to be stubborn about pinning nicely to the Windows 7 taskbar … the solution for me was to add these to the eclipse-php.ini
–launcher.vm
C:\Program Files\Java\jre7\bin
where C:\Program Files\Java\jre7\bin is the path of the installed jre on your system.
[rb]Custom doctrine count query
0Sometimes you may need to use count with the index column rather than *, because of some dark corners of sql driven databases. Though this is somehow rare, this is how you could do it with Doctrine … this example is part of a symfony 1.4 project(place the file in any of the /lib dirs … app ones or global one):
<?php
class Custom_Doctrine_Query extends Doctrine_Query {
public static function create($conn = null, $class = null)
{
if ( ! $class) {
$class = 'Custom_Doctrine_Query';
}
return new $class($conn);
}
public function getCustomCountSqlQuery()
{
// triggers dql parsing/processing
$this->getSqlQuery(array(), false); // this is ugly
// initialize temporary variables
$where  = $this->_sqlParts['where'];
$having = $this->_sqlParts['having'];
$groupby = $this->_sqlParts['groupby'];
$rootAlias = $this->getRootAlias();
$tableAlias = $this->getSqlTableAlias($rootAlias);
$primaryKey = $tableAlias . '.' . $this->_queryComponents[$rootAlias]['table']->getColumnName( $this->_queryComponents[$rootAlias]['table']->getIdentifier());
// Build the query base
$q = 'SELECT COUNT(' . $primaryKey . ') AS ' . $this->_conn->quoteIdentifier('num_results') . ' FROM ';
// Build the from clause
$from = $this->_buildSqlFromPart(true);
// Build the where clause
$where = ( ! empty($where)) ? ' WHERE ' . implode(' ', $where) : '';
// Build the group by clause
$groupby = ( ! empty($groupby)) ? ' GROUP BY ' . implode(', ', $groupby) : '';
// Build the having clause
$having = ( ! empty($having)) ? ' HAVING ' . implode(' AND ', $having) : '';
// Building the from clause and finishing query
if (count($this->_queryComponents) == 1 && empty($having)) {
$q .= $from . $where . $groupby . $having;
} else {
// Subselect fields will contain only the pk of root entity
$ta = $this->_conn->quoteIdentifier($tableAlias);
$map = $this->getRootDeclaration();
$idColumnNames = $map['table']->getIdentifierColumnNames();
$pkFields = $ta . '.' . implode(', ' . $ta . '.', $this->_conn->quoteMultipleIdentifier($idColumnNames));
// We need to do some magic in select fields if the query contain anything in having clause
$selectFields = $pkFields;
if ( ! empty($having)) {
// For each field defined in select clause
foreach ($this->_sqlParts['select'] as $field) {
// We only include aggregate expressions to count query
// This is needed because HAVING clause will use field aliases
if (strpos($field, '(') !== false) {
$selectFields .= ', ' . $field;
}
}
// Add having fields that got stripped out of select
preg_match_all('/`[a-z0-9_]+`\.`[a-z0-9_]+`/i', $having, $matches, PREG_PATTERN_ORDER);
if (count($matches[0]) > 0) {
$selectFields .= ', ' . implode(', ', array_unique($matches[0]));
}
}
// If we do not have a custom group by, apply the default one
if (empty($groupby)) {
$groupby = ' GROUP BY ' . $pkFields;
}
$q .= '(SELECT ' . $selectFields . ' FROM ' . $from . $where . $groupby . $having . ') '
. $this->_conn->quoteIdentifier('dctrn_count_query');
}
return $q;
}
public function count($params = array())
{
$q = $this->getCustomCountSqlQuery();
$params = $this->getCountQueryParams($params);
$params = $this->_conn->convertBooleans($params);
if ($this->_resultCache) {
$conn = $this->getConnection();
$cacheDriver = $this->getResultCacheDriver();
$hash = $this->getResultCacheHash($params).'_count';
$cached = ($this->_expireResultCache) ? false : $cacheDriver->fetch($hash);
if ($cached === false) {
// cache miss
$results = $this->getConnection()->fetchAll($q, $params);
$cacheDriver->save($hash, serialize($results), $this->getResultCacheLifeSpan());
} else {
$results = unserialize($cached);
}
} else {
$results = $this->getConnection()->fetchAll($q, $params);
}
if (count($results) > 1) {
$count = count($results);
} else {
if (isset($results[0])) {
$results[0] = array_change_key_case($results[0], CASE_LOWER);
$count = $results[0]['num_results'];
} else {
$count = 0;
}
}
return (int) $count;
}
}
The usage of the above class should be something like this:
$query = Custom_Doctrine_Query::create()->from('TargetTable t');
$count = $query->count();
or the bulky way omitting the static create method:
$query = Doctrine_Query::create(null, 'Custom_Doctrine_Query')->from('TargetTable t');
$count = $query->count();
The result of the above queries should be something like “SELECT COUNT(index_field) from target_table”.
WTH swiftmailer
0Now it’s kindda obvious that swift mailer is the best php mail library, but as any other great php library it sometimes lets you right in the middle of nowhere, when you’re thinking everything should be fine. This was the case with a freshly downloaded version … everything went fine until Swift_KeyCache_KeyCacheInputStream interface not found in … to shorten the story … swift looks for that interface which is expected to be in the file KeyCache.php … the declaration seems to be missing from the downloaded package … the fix is pretty simple(though there is probably a good reason why it isn’t there anymore, but for a quick fix will do) … open /classes/Swift/KeyCache.php and add these lines:
interface Swift_KeyCache_KeyCacheInputStream extends Swift_InputByteStream
{
public function setKeyCache(Swift_KeyCache $keyCache);
public function setNsKey($nsKey);
public function setItemKey($itemKey);
public function setWriteThroughStream(Swift_InputByteStream $is);
public function __clone();
}
save it … and you’re good to go.
[rb]symfony’s 1.4 sfForm isValid()
0Someone asked me a few days ago how can he use the sfform validation feature to validate an object created “by hand”. While i’m not quite sure yet of the usage of such a thing, here’s my approach(we’ll assume we have a table called Selections with 4 fields like id(incremental/key/bigint), target_id(bigint), type(varchar), name(varchar)):
public function executeAdd(sfWebRequest $request) {
if($request->isXmlHttpRequest()) {
$this->setLayout(false);
$this->forward404Unless($id = $request->getParameter('id'));
$this->forward404Unless($type = $request->getParameter('type'));
$selection = new Selections();
$selection->setTargetId($id);
$selection->setType(ucfirst($type));
$selection->setName('DEFAULT');
$form = new SelectionsForm(null, array(), false);
$values = $selection->toArray();
$form->bind($values);
if($form->isValid()) { $form->save(); echo 'OK'; }
else {
echo 'ERROR';
}
return sfView::NONE;
} else $this->forward404();
}
[rb] Removing textframe linkage with applescript
0You may sometimes need to be able to remove linkage between text frames in a particular document in Indesign. this script might come to the rescue:
tell application "Adobe InDesign CS2"
set theObjs to selection
if theObjs is equal to {} then
set theObjs to every text frame of document 1
end if
tell document 1 to set thebaseframe to make new text frame
repeat with tos in theObjs
if (class of tos as string) = "text frame" then
if end text frame of tos is not tos then
set next text frame of tos to next text frame of thebaseframe
set previous text frame of tos to previous text frame of thebaseframe
set autoflow thread orphaned of tos to true
end if
end if
end repeat
tell document 1 to delete thebaseframe
end tell
Extending illustrator capabilities with applescript
0While Illustrator offers a range of selection options that most of the time are enough for a particular scope, you might sometimes need to deal with a lot of stuff that come from other programs. This tiny script scrap might come to the rescue in many occasions:
tell application "Adobe Illustrator" set sel to selection set target to item 1 of sel set cls to class of target set objs to every page item of document 1 repeat with o in objs if (class of o is equal to cls) then set selected of o to true end if end repeat end tell
