This blog is NOFOLLOW Free!






Necajitii - Un 2 si restu 3

TRACK TOP
Filed in Fara nume.
1 comment filed

If you can see this, then you might need a Flash Player upgrade or you need to install Flash Player if it's missing. Get Flash Player from Adobe.
» Powered by XHTML Video Embed

Una dintre piesele belea, o parodie la Un 2 si 3 de zero a lui B.U.G. Mafia ce merita ascultata. Desi piesa are ceva ani, inca este “de actualitate” daca pot sa zic asa. Auditie placuta. Multumiri lui Ovidel46 pentru mana de ajutor in ceea ce priveste gasirea piesei de mai sus.

Versurile se gasesc aici.


BuyBox.ro - si live deployment-ul

TRACK TOP
Filed in Rant, Securitate.
No comments yet. Be the first to comment!

Deshid o nouă categorie cu acest post și anume o să îmi dau cu părerea și despre securitate. Știu că oricine poate să-și dea cu părerea, dar pe barba mea că nu e cazul de fața. Nu îmi stă în fire să îmi dau cu părerea dacă nu e nimic de zis.

Nu știu cum se face, dar în țărișoara noastră eCommerce + securitate sunt două concepte ce par a fi mutual exclusive, altfel spus sunt disjuncte. Cel puțin cam așa se întâmplă în ultima vreme. Dacă tot faceți update la site sau a dat tanti Tanța cu mătura pe tastatură, măcar puneți în puii mei o pagină de offline, sau băgați erorile în log, în loc să le băgați in browser.

Fatal error: require() [function.require]: Failed opening required ‘admin/encriptare.php’ (include_path=’.') in /[…]/index.php on line 13

Știu că este doar un simplu path disclosure, dar e un semn bun faptul că serverul acela nu prea e configurat pentru “producție”.

Amy the Squirrel - A walk in the Park

TRACK TOP
Filed in Videos.
1 comment filed

O chestie de aproape 4 minute ce merita din plin să fie vazută. Via Fra …

If you can see this, then you might need a Flash Player upgrade or you need to install Flash Player if it's missing. Get Flash Player from Adobe.
» Powered by XHTML Video Embed

urlencode()/rawurlencode() complet

TRACK TOP
Filed in Programare.
No comments yet. Be the first to comment!

Exceptând faptul ca Mr. Google bușește validarea blogului (deși W3 nu citește resursele externe = se validează), deasemenea exceptând faptul că WordPress mai trage câte o gherlă și refuză să pună conținut valid, este cunoscut faptul că am un oarecare fetiș cu standardele. În concluzie depun eforturi reale pentru a le respecta. Din păcate există situații rare în care caractere arbitrare din UTF-8 duc la invalidarea paginilor. Un exemplu bun este atunci când se compun link-uri ce conțin caractere non-ASCII. Soluția evidentă este URL encoding, dar din păcate funcția urlencode() din PHP, precum și rawurlencode() are boala de a omite caracterele menționate mai sus. Din moment ce dezvoltatorii PHP refuză introducerea unui flag pentru a putea face o codare completă a unui șir de caractere, există soluții ce pot fi aplicate la nivel de PHP. Soluția propusă de către subsemnatul depinde doar de componente din core (PCRE este parte a PHP core!).

function url_encode_all($text)
    {
        return preg_replace(‘/./e’, "sprintf(’%%%02X’, ord(’\\0′))", $text);
    }

MySQL, arbori, o singură tabelă, cheile străine si un exemplu în Kohana

TRACK TOP
Filed in Programare.
No comments yet. Be the first to comment!

Aparent am o poveste de spus. Ei bine și de data aceasta aparențele nu înșeală. M-am lovit de suficiente ori de problema arborilor stocați în baze de date, în special atunci când este vorba de o structură de categorii. Cum nu sunt un mare fan al procedurilor stocate și al trigger-elor, sunt de părere că impunând o constrângere de cheie străina problema se rezolvă mult mai elegant atunci când vine vorba să se șteargă toată ierarhia. MyISAM nu știe el de chei străine deci aici vine în ajutor InnoDB. InnoDB știe de chei străine, dar cel mai probabil prin transformarea tabelei problema arborelui nu se rezolvă de la sine deoarece nu se pot impune constrângerile de cheie străina.

Ideea este următoarea: pentru a impune o cheie străina folosind MySQL și InnoDB este nevoie ca structura arborelui să fie corecta și aceasta să convină lui InnoDB. A doua parte este partea spinoasă. Cel mai probabil un arbore corect definit are un lucru esențial ce îi lipsește. Se dă următoarea structură de bază:

CREATE TABLE `trees` (
`id` INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`parent_id` INT( 11 ) UNSIGNED NOT NULL DEFAULT ‘1′,
`data` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
INDEX ( `parent_id` )
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci

Precum se observă schema de date este corectă iar aparent nu pot apărea probleme. Se dă chiar următorul arbore:

1, 0, a
2, 0, b
3, 1, c
4, 1, d
5, 3, e
6, 2, f

Deși (aparent) la prima vedere structural este corect, dacă se rulează interogarea ce ar trebui sa pună constrângerea:

ALTER TABLE `trees` ADD FOREIGN KEY ( `parent_id` ) REFERENCES `trees` (
`id`
) ON DELETE CASCADE ;

o să dea o eroare de MySQL de toată frumusețea, ceva gen:

#1452 - Cannot add or update a child row: a foreign key constraint fails
([...]`, CONSTRAINT `[...]` FOREIGN KEY (`parent_id`)
REFERENCES `trees` (`id`) ON DELETE CASCADE)

Cei cu privirea mai ageră poate că s-au prins de soluție. Nu întâmplător i-am dat valoare implicită 1 lui parent_id, ba chiar mai mult, exemplul dat de mine nu este UN arbore, ci mai mulți arbori stocați în aceeași tabelă. Am dat acest exemplu pentru că am întâlnit de suficiente ori în practică asemenea implementări ce mai încolo îmi dădeau bătăi de cap. Ba chiar am moștenit o astfel de baza de date pentru un proiect. Ceea ce confirmă zicala care spune faptul că web developerii sug la SQL - iar cum sunt și eu în breasla lor mă auto-includ. Dar din când în când, mai există și momente de deșteptare.

Soluția sună cam asa: se face backup la date. Cheile primare nu se salvează, coloana parent_id ce va deveni cheie străina se incrementează cu o unitate dacă este vorba de o implementare precum cea din exemplul meu, dacă nu, atunci se adaptează. Se golește tabela. Se aplică iarăși codul de mai sus pentru crearea cheii străine (ALTER TABLE bla, bla, bla). În mod deloc surprinzător, aceasta va funcționa fără probleme. Nu va mai da eroarea #1452. Dar, pentru a continua, este imperativ ca această înregistrare să se găsească în tabelă:

INSERT INTO `trees` (
`id` ,
`parent_id` ,
`data`
)
VALUES (
‘1′, ‘1′, ‘root’
);

‘root’ nu e musai să fie ‘root’. Poate fi și ‘rădăcină’, dar cum personal scriu mai rar soft pentru România, prefer denumirile în Engleză. Aceasta trebuie să fie rădăcina arborelui. O înregistrare de genul (0, 0, ‘root’) este invalidă, deci nu va putea fi folosită pentru a valida implementarea originală. De aici se pot insera mai departe înregistrările, fără bătăi de cap atâta timp cât se păstrează integritatea relației cheie primară - cheie străină. De altfel, această înregistrare NU trebuie ștearsă. Dacă se șterge, se va șterge automat tot arborele. Este evident … dacă tai un copac de la rădăcina, cade cu totul. Dacă tai doar o creangă, restul copacului nu este afectat. În concluzie, dacă datele sunt manipulate corect, nu pot apărea probleme. Mai departe se poate insera noul arbore:

INSERT INTO `trees` (
`parent_id` ,
`data`
)
VALUES (
1, ‘a’
), (
1, ‘b’
), (
2, ‘c’
), (
2, ‘d’,
), (
4, ‘e’
), (
3, ‘f’
);

Se va obține rezultatul dorit inițial. Iar constrângerea își face magia: spre exemplu dacă se șterge (2, 1, ‘a’), atunci automat se vor șterge și (4, 2, ‘c’), (5, 2, ‘d’) și (6, 4, ‘e’) pentru că ierarhic au ca părinte pe (2, 1, ‘a’).

Pentru că tot m-a prins microbul MVC, mai bine zis Kohana, o să dau ca exemplu un model ce tratează din punctul de vedere al aplicației problema de mai sus. Din moment ce în mod implicit Kohana este destul de restrictiv cu manipularea variabilelor, altfel spus chestii ce în mod normal PHP le tratează ca ‘Notice’ în Kohana pot da in ‘Runtime Error’, metodele sunt puțin mai stufoase în sensul că verifică integritatea înainte de a acționa. Exemple asupra a ceea ce am spus mai sus: nu se poate șterge sau actualiza o înregistrare ce este deja ștearsă. În mod normal aceste operații returnează 0, fie ca e vorba de ‘affected rows’ sau de ‘deleted rows’. Cel puțin așa se întâmplă în mod implicit în ambele situații descrise, nu am cercetat dacă este configurabil acest comportament și nici nu am de gând. Kohana prin strictețe impune modele sănătoase de programare ce nu și le însușește orice cocalar ce pune mâna pe PHP pentru faptul că variabilele încep cu $ și a auzit că poate să se simtă și el h4×0r pentru că poate programa ceva. Deci să îi dau bâte cu modelul:

class Tree_Model extends Model {

    public function __construct($id = NULL)
    {
        parent::__construct($id);
    }

    public function add_child($parent_id, $data)
    {
        $check_record = $this->db->where(‘id’, $parent_id)->get(‘trees’);

        if($check_record->count() > 0)
        {
            return $this->db->from(‘trees’)->set(array(‘parent_id’ => $parent_id, ‘data’ => $data))->insert();
        }
        else
        {
            return false;
        }
    }

    public function update_child($id, $parent_id, $data)
    {
        $check_record1 = $this->db->where(‘id’, $id)->get(‘trees’);
        $check_record2 = $this->db->where(‘id’, $parent_id)->get(‘trees’);

        if($check_record1->count() === 1 AND $check_record2->count() > 0)
        {
            return $this->db->from(‘trees’)->set(array(‘parent_id’ => $parent_id, ‘data’ => $data))->where(‘id’, $id)->update();
        }
        else
        {
            return false;
        }
    }

    public function delete_child($id)
    {
        $check_record = $this->db->where(‘id’, $id)->get(‘trees’);

        if($check_record->count() === 1 AND $id > 1)
        {
            return $this->db->from(‘trees’)->where(‘id’, $id)->delete();
        }
        else
        {
            return false;
        }
    }

}

PS: clasa este portabilă și pentru alte baze de date având în vedere faptul că am folosit ‘Database Query Builder’. Mergea si cu ORM, dar prefer o abordare puțin mai directa a problemei. În ORM nu mă mai simt stăpân pe situație. Pentru cârcotași: având în vedere că aceste tipuri de structuri de date nu prea sunt dedicate modificărilor dese, impactul de performanță datorat numărului mărit de interogări pentru a verifică integritatea este minim și merită efortul pentru a face o abordare corectă în loc să se apeleze la reguli mai puțin stricte și a depinde de erorile eventuale returnate de către baza de date (FK constraint error).

Nota: nu pot corecta comportamentul cretin al WordPress pentru a afisa corect apostrof si ghilimele.

Lista Județelor, Municipiilor, Orașelor și a Comunelor/Satelor din România

TRACK TOP
Filed in Programare.
1 comment filed

Pe post de introducere: în primul rând o să îmi cer scuze din start pentru că nu am mai scris cu diacritice de un secol, deci anumite chestii s-ar putea să sune ciudat - cel puțin până ma obișnuiesc. Dacă tot am ‘Romanian Programmers’ dat de Sfântul Windows 7, am zis să beneficiez puțin (ca porcul) pentru a-mi îndrepta această bubă în ceea ce privește scrierea propriilor articole.

Iar acum să trec la articolul pe bune. Ieri și astăzi am răscolit Internet-ul după o chestie ce să imi ofere lista pomenită în titlu. M-au ajuns din urmă zilele în care sunt pus în fața faptului de a dezvolta o asemenea aplicație ce necesită o astfel de listă/astfel de liste. Fie am găsit liste incomplete - mai bine zis un document xls de la Institutul Național de Statistică ce datează de pe vremea lui Pazvante (sau recensământul din 2002, fiecare citește ce vrea) sau lista disponibilă pe Wikipedia ce nu mă coafează din moment ce am observat inadvertențe, fie nu sunt structurate în sensul că orice sat e trecut la orașe. Deși nu am întâlnit o chestie ce să le mulțumească pe toate și anume o listă ce cuprinde și diacritice, lista de față este (relativ) completă.

Am scris un mic script ce a cules listele pomenite mai sus. Le pun la download ca fișier serializat, urmând ca fiecare sa îl convertească în formatul pe care și-l dorește: XML, JSON, SQL, etc. Mai pun și un script obosit ce ia conținutul fișierului și îl trântește în HTML  (cu var_dump() - nu m-am obosit să fac artă).

Download: lista_localitati.zip process_ro_list_output.zip

Instalarea Apache 2.2 + PHP 5.2 + MySQL 5.1 sub Windows

TRACK TOP
Filed in Programare, Tech, Windows.
No comments yet. Be the first to comment!

Ultima actualizare: 19 Aprilie 2009

Introducere

Desi exista o droaie de pachete de astea ce le contin pe toate si au o gramada de arome, pe zi ce trece ajung la concluzia ca un developer serios nu se incurca cu mizerii si isi seteaza singur mediul de dezvoltare a aplicatiilor web. Ma rog, nu toate sunt mizerii, dar majoritatea fie sunt prea stufoase, fie inutile sau inutilizabile fara lucru manual - deci mai bine faci lucru manual din start. Asta in cazul in care nu vrei sa ramai o mimoza pentru tot restul vietii care transpira cand vine vorba sa adauge module noi mediului respectiv, sau pur si simplu sa se blocheze in parametrii de configurare relativ simpli. Nu sustin faptul ca este usor. De altfel patrunderea in tainele configurarii fine necesita timp si multa documentatie citita. Dar macar vreo cateva chestii de baza ar trebui cunoscute. Iar chestiile de baza pornesc cu instalarea.

Propozitie cheie: daca iti este lene sa iti configurezi acest mediu (lucru ce nu se intampla zilnic, iar experienta acumulata este benefica) atunci oare nu iti este lene sa te apuci sa programezi catusi de cat mai mult decat aplicatii gen “hello world”? Pentru a implementa solutii de o complexitate relativ mare ce necesita varii module este nevoie de mult mai multa munca pentru documentare decat pentru a configura un mediu de dezvoltare. In plus, din moment ce nu iti cunosti bine mediul in care ruleaza aplicatiile tale, cum poti avea nesimtirea sa sustii ca ai idee foarte bine ce face propria aplicatie? De unde vei sti ca va functiona corect si este portabila pe alta masina? Intrebarile acestea sunt multe, si nu, nu am de gand sa le transform in intrebari retorice. Raspunsurile sunt mai mult sau mai putin evidente.

O sa structurez acest articol in cativa pasi destul de simplu de urmat. Este ca in cazul in care se construieste o casa: se pleaca de la fundatie, si se termina treaba cu acoperisul. Deci ordinea va respecta logica si bunul simt, cu notiunea ca desi o sa incep cu Apache, MySQL deasemenea poate fi primul pas deoarece baza de date si serverul web nu sunt interdependente. PHP se integreaza cu Apache, deci regulile anterior mentionate indica faptul ca va fi instalat dupa el - aceasta pentru a nu fi nevoit sa faci instalarea PHP de doua ori. Read the remainder of this entry »

Gnome History

TRACK TOP
Filed in Linux, Tech.
No comments yet. Be the first to comment!

Acesta este inca unul dintre acele posturi despre intalnitele “OS annoyances“. Desi primele 3 rezultate din Google Search-ul de mai sus fac referire la Windows OS, de data aceasta Gnome in implementarea Debian/Ubuntu iese la rampa. Posibil si sub alte distributii pentru ca imi miroase a problema din upstream in loc sa fie o problema a Debian+derivatii.

M-am trezit inca de dimineata cu gand rau impotriva Gnome History. Din pacate gandul meu a fost mai slab decat implementarea incapatanata a celor ce au gandit Gnome-ul din acest punct de vedere si n-au pus pe undeva o optiune pentru dezactivarea acestei functii, optiune ce sa fie demna de ‘Captain Obvious’, altfel spus, la mintea cocosului. Daca in trecut istoricul se tinea in fisierul ~/.recently-used iar un simplu:

chmod -c 400 ~/.recently-used

era suficient pentru a opri atrocitatea, in prezent (de la Gutsy si pana in prezent daca nu ma insel) lucrurile sunt sensibil mai diferite. Numele fisierului s-a schimbat intre timp in .recently-used.xbel. Nu aceasta ar fi problema esentiala daca metodele clasice ar functiona. Am incercat schimbarea ACL-urilor precum am pus mai sus: ceva le restaureaza. Am pus symlink catre /dev/null … ceva sterge link-ul si restaureaza fisierul. L-am creat de sub root si l-am lasat asa … ceva ii restaureaza ACL-urile si le pune iarasi pe contul meu. Parca era un film de acela prost cu Greuceanu ce omoara balauri alimentati cu baterii Duracell ce tot primesc resurect. Din fericire acesta a fost balaur pe 2 biti (4 capete). Cine stie bancul cu balaurul pe 8 biti, pricepe.

Metode exista, si sunt doua la numar. Prima desi functioneaza, este trista pentru ca are prostul obicei de a genera erori GTK in shell:

rm ~/.recently-used.xbel ; mkdir ~/.recently-used.xbel

Se pare ca e o piatra prea tare de rumegat pentru implementarea incapatanata prezentata mai sus.

Dar are dezavantajul erorilor din shell. Fericitii (ca mine) ce folosesc ext3 pe post de filesystem (nu cunosc utilitare echivalente pentru reiser, xfs, jfs - nu dati cu pietre) pot apela la o smecherie ce marcheaza fisierul ca immutable iar la incercarea de a face ceva, o sa se loveasca de un raspuns mai incapatanat de la Sfantul Kernel:

sudo chattr +i ~/.recently-used.xbel

Chestia asta il va opri pe mucos sa mai salveze istoricul, ba mai mult, scuteste shell-ul de erori neinteresante.

Which Scrubs character are you?

TRACK TOP
Filed in Fara nume.
No comments yet. Be the first to comment!
Which Scrubs character are you?

Dr. Cox

You are very sarcastic and bitter. You believe that everyone is always wrong and you are always right. Putting others down and making fun of them is one of your favorite passtimes.

Personality Test Results

Click Here to Take This Quiz
Brought to you by YouThink.com quizzes and personality tests.

Smart Little Bird

TRACK TOP
Filed in Videos.
3 comments filed

If you can see this, then you might need a Flash Player upgrade or you need to install Flash Player if it's missing. Get Flash Player from Adobe.
» Powered by XHTML Video Embed