Hei,
Onko mahdollista tehdä PHP:lla MySQL-tyyppinen sivutus PHP-arraylle. Eli siis AJAX-kysely (Ext JS 3.4.0) postaa palvelimelle teidot start 0 ja limit 50 jos sivutus on 50 riviä per sivu ja sitten 51-100 sivulle kaksi. Eli jos on niin millaisella PHP-koodilla/functiolla. Zend Frameworkin olla pagination luokalla tämä ei ole mahdollista koska se tarvitsee palvelimelle sivu numeron, yms. Ja Ext JS 3.4.0 ei tue ollenakkaan tälläistä.
Eli siis MySQL:ssä koodi Zend Frameworkilla on tallainen:
$sql_count = 'SELECT * FROM ' . $table .' WHERE user_id = '.$id.' AND '. $table .'.title LIKE \'%'.$query.'%\' ' .'AND '.$table.'.month = '.$db->quote($month, 'INTEGER').' AND '.$table.'.year = '.$db->quote($year, 'INTEGER').' ' . ';'; $sql = 'SELECT * FROM ' . $table . ' LEFT JOIN hours ON ' . $table . '.id=hours.task_id ' . 'AND hours.year = '.$year.' ' . 'AND hours.month = '.$month.' ' .'WHERE user_id = '.$id.' AND '. $table .'.title LIKE \'%'.$query.'%\' ' .'AND '.$table.'.month = '.$db->quote($month, 'INTEGER').' AND '.$table.'.year = '.$db->quote($year, 'INTEGER').' ' //.'AND '.$table.'.isLeaf = true ' .'ORDER BY id ASC LIMIT ' . $start . ', '. $end.';';
walkout_ kirjoitti:
Onko mahdollista tehdä PHP:lla MySQL-tyyppinen sivutus PHP-arraylle.
On, tietenkin. Siihen on jopa valmis funktio:
$sub = array_slice( $array, $start, $length, true);
Grez kirjoitti:
walkout_ kirjoitti:
Onko mahdollista tehdä PHP:lla MySQL-tyyppinen sivutus PHP-arraylle.
On, tietenkin.
$sub = array_slice( $array, $start, $end, true);
ok.. kiitos tästä testaan asap.
Oops, se kolmas parametri oli "pituus" (ei "loppu", kuten vahingossa ennen korjausta laitoin)
Joo ja tietenkin on hyvä lukea PHP-dokumentaatiota ja ei ole laitonta kopsata sieltä koodi-esimerkeejä. Mutta kun ei näistä aina niin teidä oikeia valmisfunctiota.
Ext JS 4 ja siitä ylöspäin näiden MySQL-sivus juttujen lisäksi ks. systeemi postaa myös automaattisesti sivunumeron palvelimelle joten Zend Framework -sivutusluokka toimii näillä kuin pommi.
Ext JS 4 mulla on kyllä lisenssi, joka makso paljon joten silläkin voisi tehdä mutta kun projektilla on niin kiire että ei vaan ehdi koodata kaikkea uusiksi Ext JS 4+:salla.
On vähän kummaa että nykyään Ext JS:ssä ei saa ilmaiseksi vaikka se on oletuksena GNU GPL ja jos maksaa tuotteesta niin saa tehdä suljetun lähdekoodin ohjelman. Tämä minun nykyinen projekti on GNU GPL -lisensotitu ja silti en saa ilmaiseksi Ext JS:ssä enää.
walkout_ kirjoitti:
On vähän kummaa että nykyään Ext JS:ssä ei saa ilmaiseksi vaikka se on oletuksena GNU GPL
Kuinka niin? https://www.sencha.com/legal/gpl/
Vai tarkoitatko, että vain major versiot julkaistaan GPL:näkin, eli esim. 6.0 mutta ei 6.7.
Ehkä voisit myös harkita jotain sellaista js frameworkia, jonka avointa versiota saa käyttää myös suljetun koodin tuotteissa, niitäkin näyttää olevan toista kymmentä https://en.wikipedia.org/wiki/
Sain nyt toimimaan koodin oikein näin päin:
$paginator = array_slice($json, $start, $end, false); $success = array('success' => true, 'totalCount' => $ii, 'tasks' => $paginator); echo Zend_Json::encode($success);
jos toi viimeisin olisi ollut meinaan true niin listaus olisi väärin päin eikä näin ollen toiminut oikein. Eli sivulla kaksi ei olisi näkynyt mitään.
No ei vaan sulla on taulukko php:ssä väärin päin, siinä se vika on.
Taulukon indeksien "säilyttäminen" on tarkoitettu lähinnä sitä varten, että taulukon rivit voi indeksoida käyttäen jotain muuta kuin juoksevaa numerointia. Jos kuitenkin haluat käyttää juoksevaa numerointia mutta rivien järjestys on väärä (eli jostain syystä indeksien järjestys sekaisin), niin silloin oikeastaan vain kierrät omassa koodissasi olevaa bugia tavalla, joka toimii nyt mutta on rikki taas ensi kerralla jossain toisessa yhteydessä.
Php:ssä jopa numeeriset indeksit voivat olla mielivaltaisessa järjestyksessä ja se on "ihan ok". Sen sijaan javascriptissä ja jsonissa Array-tyyppi on aina indeksoitu 0...n kasvavassa järjestyksessä. Eli jos muunnat php-taulukon jsoniksi, niin rivit voivat asettua eri järjestykseen, mikäli php-taulukon indeksointi on jostain syystä epäjärjestyksessä.
Oikeastaan saattaa käydä jopa niin, että php:n json_encode()* sarjallistaa taulukon tällöin Arrayn sijaan Objectiksi, mutta ainakin Firefoxin ja Chromen kanssa lopputulos on jossain mielessä sama, koska niiden implementaatio toimii siten, että Objectin numeeriset jäsenet asettuvat aina kasvavaan järjestykseen oliota iteroidessa. Kyse ei kuitenkaan ole standardista ominaisuudesta, joten siihen ei kannata luottaa.
Alla esimerkki siitä, mitä edellisessä kappaleessa yritin selittää:
// Php-taulukon muuttaminen jsoniksi print json_encode([0 => 'a', 2 => 'b', 1 => 'c']); // Tulostaa {"0": "a", "2": "b", "1": "c"} // Selaimessa järjestys kuitenkin voi muuttua: console.log({0: 'a', 2: 'b', 1: 'c'}) // Tulostaa todennäköisesti {0: 'a', 1: 'c', 2: 'b'}
* Voi olla, että Zendin enkooderi käyttää omaa implementaatiotaan ja lopputulos on siksi esimerkistäni poiketen esim. (json-)Objectin sijaan Array mutta indeksit ns. loogisessa järjestyksessä.
Siis ohjelma hakee oletuksena desc-järjestyksessä palvelimelta dataa PHP-taulukkoon jos sitä ei ole eriksen määritetty onko se DESC vai ASC. Kiitos kuitenkin huomautkesta sillä minun JavaScript-kutsussa oli ASC ja PHP-puolella DESC.
Sitten ORDER BY on oletuksena muuten created_date eli rivin luontipäivä.
Eli ei voi toimia oikein jos kerran Ext JS -taulukossa on ORDER BY ID.
Homma on siis tämä:
https://developers.freshdesk.com/api/
Siis minun koodi ei ole tehty oikein verraten siihen miten Freshdesk tomii.
$phpNative = Zend_Json::decode($body); var_dump($phpNative);
Tulostaa, että se on Array ja on nousevassa järjestyksessä.
Sitten alkaa koodi:
$json = array(); $ii = 0; foreach ($phpNative as $key => $value) { $json[$ii]['id'] = $value['id']; $ii++; }
var_dump($json);
Tulostaa, että se on Array ja indexit ovat nousevassa järjestyksessä mutta eivät sekaisin epäloogisesti.
var_dump(Zend_Json::encode($success));
Tulostaa, että koko hoito on String.
Tuossa sun foreach-loopissasi ei kyllä ole mitään järkeä. SQL-kysely* palauttaa jo valmiiksi taulukon juoksevalla numeroinnilla eli sitä ei tarvitse resetoida. On myös aika turhaa yrittää optimoida lukemalla pelkät id:t taulukkoon. Voit siis palauttaa suoraan kyselyn tuloksen sellaisenaan tai korkeintaan suotia pois sellaiset kentät, mitä ei ole tarkoitus näyttää julkisesti ollenkaan.
* Tai mikä ihme "$phpNative" onkaan. Muuttujan nimi on todella huono, se ei oletettavasti kerro mitään muuttujan sisältämän datan luonteesta.
Samoin että mikä ihmeen "$ii"? Vaikka ei olekaan mitään pakkoa käyttää aina indeksilaskurina juuri $i-nimistä muuttujaa, niin on aika outoa, että päätät rikkoa käytäntöä keksimällä uudeksi nimeksi $ii. Olisi parempi käyttää joko yleisiä käytäntöjä tai tietyissä tilanteissa nimetä laskurikin havainnollisesti käyttötarkoituksensa mukaisesti.
Siis cURL REST Client hakee ensin Ticketit Freshdeskistä ja tekee niistä vain JSON-stringin joten se pitää ensin decodata koodilla:
$phpNative = Zend_Json::decode($body);
Ja sitten ajaa Foreach loopilla Arrayksi, josta encodataan sitten EXt JS 3.4.0 tomiva JSON-palaute.
Koko ohjelmassa ei ole MySQL-käytetty muuta kuin APIKey:n ja Freshdesk URL:n hakemiseen minne REST-kutsu tehdään.
Ja MySQL tietokannassa APIKey on salattu tehokkaammalla salauksella kuin esim. mcrypt. Ja mcrypt ei ees toimi enää uusimmissa Unbuntu Server LTS versioissa koska se funktio on poistettu uusimmista PHP-verioista.
walkout_ kirjoitti:
Ja MySQL tietokannassa APIKey on salattu tehokkaammalla salauksella kuin esim. mcrypt.
Jokseenkin huvittavan kuuloinen lausahdus, kun mcrypt ei ole mikään salausalgoritmi, vaan PHP-laajennus, jossa on tuki useille erilaisille salausalgortimeille, kuten vaikkapa AES256.
Toki voi olla että käytät jotain sellaista algoritmia, joka on tehokkaampi kuin mikään mcryptistä löytyvä, mutta silti huvittaa että miksi et vaan sano mitä algoritmia käytät vaan kirjoittele tuollaista diipadaapaa.
Toivottavasti tästä nyt ei tule sellainen kuva että jotenkin suosittelisin mcryptin käyttöä - ei tietenkään, sehän on poistettu käytöstäkin uusimmissa PHP-versioissa. Pointti oli ihan puhtaasti huvitus asian vierestä puhumisesta.
Millä tavalla tuo alkuperäinen JSON ($body) ja lopullinen JSON eroavat toisistaan? Edellisessä sepustuksessa nähtyjen koodien perusteella samaan lopputulokseen pääsisi jollakin seuraavista riveistä:
$tulos = $body; $tulos = Zend_Json::encode(array_values(Zend_Json::decode($body))); $tulos = Zend_Json::encode(array_column(Zend_Json::decode($body), 'id'));
Kai siinä oli tarkoitus, että PHP päässä palastellaan siitä vain "yksi sivu" eli 50 tietuetta per pyyntö eteenpäin (jossa tietenkin on todennäköisesti suhteellisen vähän järkeä ja luultavasti (toteutuksesta riippuen) enemmän haittoja kuin hyötyjä)
Grez, viittasin tuohon jälkimmäisen viestin koodailuun, jossa vain kerätään taulukon id:t silmukassa toiseen taulukkoon $ii-indeksimuuttujalla. Toki tähän voidaan lisätä array_slice joko array_valuen tilalle tai array_columnin ympärille.
Opinpanhan nyht pari uutta PHP-functiota.
Mutta luulempa, että foreach-silmukkaa on käytettävä silti koska kyseessä on siis Timesheet joka hakee Freshdesk-pilvipalvelusta ensin Tiketit ja niiden tietueet ja sen jälkeen faoreach-silmukan sisällä uusi cURL-kutsu joka hakee tiketeille kaikki käytetyt työtunnit ja laskee ne kalenterimaiseen taulkukkoon yhteen päiväväkohteisesti.
Niin laitoin kyllä enemmän riejäjä per sivu kuin 50. Mutta luulen että ainakin vanhoissa koneissa Ext JS sekoittaa vaan selaimen ja antaa siihen kuuluvia virheilmoituksia jos rivejä yhdelle sivulle haetaan esim. 20000 kpl.
Eli millaista projektia olen siis tekämssä? No: https://www.i4ware.fi/products/i4ware-timesheet-for-freshdesk/
Ja lähdekoodi tullaan julkaisemaan GNU GPL, v. 3 -lisenssin alla ihan ilmaiseksi.
Aihe on jo aika vanha, joten et voi enää vastata siihen.