These are chat archives for PHPixie/Hotline

20th
Apr 2016
Roman Tsiupa
@dracony
Apr 20 2016 06:15
@Linfuby кстати вместо костыля настройки связей можно получить по
$orm->builder()->maps()->relationship()
Vadim Meling
@Linfuby
Apr 20 2016 06:52
По нему к сожалению нельзя пройтись в цикле.
Roman Tsiupa
@dracony
Apr 20 2016 11:08
хммм да надо знать имена моделей
хм
добавю метод
Vadim Meling
@Linfuby
Apr 20 2016 11:48
Спасибо.
Кстати вчера нашел небольшой баг в модуле E-mail для версии 2
https://github.com/dracony/PHPixie-swift-mailer/blob/master/classes/PHPixie/Email.php#L60
Переменная называется $_instances А в этой функции испольуется без нижнего подчеркивания
Crow
@2x2studio
Apr 20 2016 11:53
@dracony а как обстоят дела с выборкой из субд и с указанием ключа. Чеб массив возращался асоциативный по требуемому ключу ?
Vadim Meling
@Linfuby
Apr 20 2016 11:53
Нет такого... Самому хочется такое.
Нужна функция аналог asArray() только например asAssoc($fieldName = null) где $fieldName имя поля по которому строить массив. Если null то по Идентификатору
Или просто модифицировать asArray() добавив в нее $fieldName, а если null то строить обычный массив
Crow
@2x2studio
Apr 20 2016 11:55
@Linfuby да говорили мы об этом уже месяца 2 назад. Тока я пул реквест не отравил (
я уже тоде нмного примахался бегать по массиву и отстраиваться )
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 13:55
@dracony using ORM is there a way to orderAscendingBy() specifying a relation like in the where()?
@dracony using the category articles sample,
orm->query('article')->orderAscendingBy('category.name')->find( 'array('category');
there's no problem using 'category.name' in the where() function, but using it in the order() functions throws a field not found exception from the DB, I understand that it's not resolving/mapping fields llike the where() function does
Roman Tsiupa
@dracony
Apr 20 2016 17:55
@2x2studio @Linfuby
$data = $orm->...->find()->asArray();
$map = array_combine(array_map(function($a) {return $a->someField;}, $data), $data);
ну да, не очень очевидно получилось (
@maxidirienzo since relationship preloading works after the original data set was retrieved
you cant sort by relationship
but
you can do it with php obviously
usort(function($a, $b) {return $a->category->name <=> $b->category->name;}, $data);
the <=> operator is really useful for that
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 19:08
@dracony I know but won't work, need to page thousands of records retrieved with offset() and limit(), need to be able to sort in the query
Roman Tsiupa
@dracony
Apr 20 2016 19:38
ah
I see
In that case you'll need to get tricky
either modify the query manually
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 19:40
hmmm is there a way to dump the final SQL?
Roman Tsiupa
@dracony
Apr 20 2016 19:40
or maybe store category name in the article table
there is
but I can alreay tell you that there is no JOIN there when loading articles
the categories are loaded with a separate query
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 19:41
oh i see, and when you run the where?
Roman Tsiupa
@dracony
Apr 20 2016 19:41
and the articles query itself doesnt have the joins in it
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 19:42
hmmm can I get the database object from the orm and manually join and order?
Roman Tsiupa
@dracony
Apr 20 2016 19:42
yes
well
easier than that
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 19:43
i'm all ears :)
Roman Tsiupa
@dracony
Apr 20 2016 19:45
$query = ....;
// build queyr plan without executing
$plan = $query->planFind(array('category'));

$dbQuery = $plan->queryStep()->query();

//modify dbQuery

$results = $plan->execute();
when modifying dbquery you'll need to join the category table
and order it
but be sure to limit the fields returned by the query
so only the fileds that belong to the articles table are returned
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 19:47
let me check this out
```$dbQuery = $plan->queryStep()->query();
this returns an object, not the SQL
$dbQuery = $plan->queryStep()->query();
Roman Tsiupa
@dracony
Apr 20 2016 19:50
yes
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 19:50
not sure why is $dbQuery needed then if $plan->execute() is called
Roman Tsiupa
@dracony
Apr 20 2016 19:51
$dbQuery->join('categories', null, 'left')->on('articles.category_id', 'categories.id')->orderBy('categories.name');
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 19:51
ohhh i see
Roman Tsiupa
@dracony
Apr 20 2016 19:51
you modify the dbQuery (which is a Database query)
before executing the plan
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 19:52
and $query->planFind() is called instead of the ORM call?
Roman Tsiupa
@dracony
Apr 20 2016 19:52
$dbQuery->fields(array($database->sqlExpression('articles.*')))
yes
actually calling ->find() on the query
is the same as
$query->planFind()->execute();
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 19:54
ok.. but $query is obtained calling $query = $orm->query(...)? or is there another way./
?
Roman Tsiupa
@dracony
Apr 20 2016 19:55
well
yes
any orm query
$orm->query('article')
etc
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 19:58
ok, made it work, but got an ambiguous column name error, seems $orm.where() do not prepend the entity alias
Roman Tsiupa
@dracony
Apr 20 2016 19:59
hmm
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 20:00
I'm doing a user join city query, have state_id on both tables (yes, i know....)
when filtering on state_id, got the ambiguous column name error
$orm->query('user')->where('state_id', 5); then your plan, join, etc
Roman Tsiupa
@dracony
Apr 20 2016 20:02
I see
in that case
perhaps a better solution would be to make a separate query with Database
to gt the ids of paginated items
then make an ORM query
using plain
->in($idsArray)
this way you wouldnt need to fiddle around query plans
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 20:04
hmmm if I fetch a table rows only with $database, is there a way to wrap the row in an ORM entity?
Roman Tsiupa
@dracony
Apr 20 2016 20:19
yes
although it's easier to use a ->in query tbh
but it can be done
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 20:20
a -> in the query?
Roman Tsiupa
@dracony
Apr 20 2016 20:21
$orm->query('articles')->in($listOfIds)->find()
since this is a query by primary key
it will be super fast
but of course you can also turn any database result into orm
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 20:22
ya, but I lose sorting again
if $listOfIds contains rows with 2 different joined table values, those may be unsorted, disregarding that the corresponding rows are there
Roman Tsiupa
@dracony
Apr 20 2016 20:23
$ormBuilder = $orm->builder();
$resultStep = $ormBuilder->steps->reusableResult($yourDatabaseQuery);
$loader = $ormBuilder->loaders->reusableResult($orm->repository('article'), $resultStep);
$data = $loader->asArray();
this way you can turn any database query into an ORM result
but
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 20:24
$loader would be the ORM entity correct?
Roman Tsiupa
@dracony
Apr 20 2016 20:24
$loader is the same as just calling $query->find()
it's an iterator
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 20:25
ok, got it
let's try this up
Roman Tsiupa
@dracony
Apr 20 2016 20:25
on th other hand after you got your items using an ->in() you could easily sort them with usort()
like I suggested from the beginning
since you only have a small subset of items
usort wont slow you down anymore
the problem with using the loader directly is you can't specify preloaded items
categories in your example
well you can also attach preloading manually though
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 20:27
yes, got that ;)
Roman Tsiupa
@dracony
Apr 20 2016 20:28
you could cheat a bit though =)
you could join category data in your database query
and ORM will think those are just article fields
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 20:31
correct, I don't need to save() or anything so that's fine too
Roman Tsiupa
@dracony
Apr 20 2016 20:33
well
even save would work technically
since it only saves modified fields
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 20:34
got "This plan step has not been executed yet." error
        $query
            ->offset($pagefrom)
            ->limit($pagesize);


        $ormBuilder = $this->orm->builder();
        $resultStep = $ormBuilder->steps()->reusableResult($query);
        $rs = $ormBuilder->loaders()->reusableResult($this->orm->repository('user'), $resultStep);
on while ($rs as $r)....
Roman Tsiupa
@dracony
Apr 20 2016 20:37
$resultStep->execute()
after building it
missed it
the step has to be executed to run the query
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 20:56
ok, works, but only returns 1 row :s
Roman Tsiupa
@dracony
Apr 20 2016 20:57
are you sure the query returned more?
you can check raw data by print_r($resultStep->result()) after executing it
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 21:00
SQL returns 2 rows, checked
`` foreach ($rs as $r) {
        $rs = $ormBuilder->loaders()->reusableResult($this->orm->repository('user'), $resultStep);
```
foreach ($rs as $r) {
} ```
damn formatter
```
foreach ($rs as $r) { }
foreach ($rs as $r) { }
get 1 row in the foreach()
fixed, my fault!!!! got a value on session, didn't realize, sorry!
Roman Tsiupa
@dracony
Apr 20 2016 21:05
yay)
Maxi Di Rienzo
@maxidirienzo
Apr 20 2016 21:14
thanks a lot @dracony !
Roman Tsiupa
@dracony
Apr 20 2016 21:15
anytime=)