Friday, February 20, 2015

Boban Acimovic Consulting | Joining non-related tables in Propel 1.6

Boban Acimovic Consulting | Joining non-related tables in Propel 1.6



I had this problem few days ago and I couldn’t find any useful information on the Internet. I had to browse through Propel internals to find this out and it would be pity not to share it with others. So let’s start with an example:

$accounts = AccountQuery::create()
->joinWith('Account.AdditionalData')
->addJoin(AdditionalDataPeer::VAL, CountryPeer::ID)
->withColumn('country.name', 'CountryName')
->find();
Someone may ask why Country and Account objects have no relation. Well, this is just an example, but imagine that table AdditionalData contain many different values, so we can’t really make any foreign reference as it would have to reference many different tables, which is not possible. There may be other reasons to use something like this, but anyway let’s explain line by line how it works.

->joinWith('Account.AdditionalData')
This is just normal Propel join where we hydrate the main object with related object data.

->addJoin(AdditionalDataPeer::VAL, CountryPeer::ID)
This is the way how we can define additional join with non-related table. The first value, AdditionalDataPeer::VAL represents the field name in the left table and CountryPeer::Id it’s corresponding field in the right table. These constants are defined in base peer classes. As third parameter here you can define the type of join, but I have used just default (inner join). This works fine except the main object is not hydrated with the related object data. Unfortunately, this is not possible using with() method as with() works only with previous join(). Fortunately, there is another way using:

->withColumn('country.name', 'CountryName')
First parameter here is the real table name concatenated with real column name and the second one is an alias name for this column. You can include as many columns from the related table as you want. It’s probably possible to concatenate some predefined Propel constants for the first parameter, like CountryPeer::TABLE_NAME . ‘.’ . CountryPeer::ID, but I haven’t tried that.
And like the documentation for withColumn() says, you can use this value in the resulting object by method getVirtualColumn():

foreach ($accounts as $account) {
print $account->getVirtualColumn('CountryName') . PHP_EOL;
}
I hope this may help someone :)

javascript - How to make a loading indicator for every asynchronous action (using $q) in an angularjs-app - Stack Overflow

javascript - How to make a loading indicator for every asynchronous action (using $q) in an angularjs-app - Stack Overflow



Although I find it very complicated, unnecessary and probably broken, you could decorate $qand override its defer function.
Every time someone asks for a new defer() it runs your own version which also increments a counter. Before handing out the defer object, you register a finally callback (Angular 1.2.0 only but always may fit, too) to decrement the counter.
Finally, you add a watch to $rootScope to monitor when this counter is greater than 0 (faster than having pendingPromisses in $rootScope and bind like ng-show="pendingPromisses > 0").
app.config(function($provide) {
    $provide.decorator('$q', ['$delegate', '$rootScope', function($delegate, $rootScope) {
      var pendingPromisses = 0;
      $rootScope.$watch(
        function() { return pendingPromisses > 0; }, 
        function(loading) { $rootScope.loading = loading; }
      );
      var $q = $delegate;
      var origDefer = $q.defer;
      $q.defer = function() {
        var defer = origDefer();
        pendingPromisses++;
        defer.promise.finally(function() {
          pendingPromisses--;
        });
        return defer;
      };
      return $q;
    }]);
});
Then, view bound to a scope that inherits from $rootScope can have:
<span ng-show="loading">Loading, please wait</span>
(this won't work in directives with isolate scopes)
See it live here.

Calling Commands Within Commands in Symfony2 | Craft It Online!

Calling Commands Within Commands in Symfony2 | Craft It Online!



I was trying to create a command. The intent goes beyond the exercise as there are some guys already who are trying to setup an entire system from the console. But for now we will just do the command creation. The idea is to call commands within commands and for that we have the following information here which is too simple for our purposes and alsohere where we are told how to call commands within commands but the documentation does not elaborate too much on its uses and interesting applications.
So here I paste the code for a basic command:
<?php
namespace Cordova\CrownBundle\Command;
 
use Symfony\Bundle\FrameworkBundle\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\ArrayInput;
 
class SetupCommand extends Command
{
    protected function configure()
    {
        $this
            ->setName('crown:setup')
            ->setDescription('Crown Setup')
            ->addArgument('yesno', InputArgument::REQUIRED, 'Do you want to fire up setup? (y/n)')
            //->addOption('yell', null, InputOption::VALUE_NONE, 'If set, the task will yell in uppercase letters')
        ;
    }
 
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $yesno = $input->getArgument('yesno');
        if ($yesno == 'y') {
            $text = 'Running setup ... ';
            $command = $this->getApplication()->find('doctrine:fixtures:load');
            $arguments = array(
                //'--force' => true
                ''
            );
            $input = new ArrayInput($arguments);
            $returnCode = $command->run($input, $output);
            if($returnCode == 0) {
                $text .= 'fixtures successfully loaded ...';
            }
 
        } else {
            $text = 'Exiting ...';
        }
 
        /*if ($input->getOption('yell')) {
            $text = strtoupper($text);
        }*/
 
        $output->writeln($text);
    }
}
For now we just are loading the fixtures of our system. Of course this command at the moment is found redundant. However it can be well expanded into something more complex. Thanks for reading. Please consider donating.