Clicky

Skocz do zawartości


Zdjęcie
- - - - -

[K2] Dict - dane słownikowe

1 odpowiedź w tym temacie

  • Zaloguj się, aby dodać odpowiedź

#1 phpion

phpion

    Senior Mastah

  • Użytkownik
  • PipPipPip
  • 774 postów
  • Skąd:Sosnowiec, Dąbrowa Górnicza

Napisano 15 czerwiec 2012 - 11:09

Witam,
udostępniam/daję pod opinię kolejny moduł z paczki Kohana 2.3.4.5. Tym razem jest to moduł służący do obsługi danych słownikowych.

O co w tym chodzi? Często pracujemy na danych typu miasta, kraje. Zazwyczaj pod kątem tych danych tworzy się osobne tabele. Sprowadziłem całość do jednego modułu składającego się z kilku tabel. Każdy słownik może mieć dowolną ilość kolumn. Musi mieć przynajmniej 1 kolumnę, która będzie się nazywać name. Można dodać kolejne kolumny (w przykładzie do miejscowości dodałem kolumnę np. położenia geograficznego).

Po stworzeniu słownika należy go zbudować (metoda build). Słownik może być stworzony jako widok (domyślnie) lub jako zwykła tabela. Pierwsze rozwiązanie ma tą zaletę, że wprowadzane dane widoczne są od razu w widoku (tabelę trzeba stworzyć od nowa - metodą build). Z drugiej strony korzystanie z widoku wymaga wykonania zapytania z JOINami (dla kolumn) oraz UNION (dla wersji językowych). Wykorzystanie konkretnego trybu pracy może więc zależeć od konkretnej potrzeby.

Kolumny w słownikach rzutowane są na odpowiedni typ danych. Wartości przechowywane są w polu typu TEXT, ale w samym widoku/tabeli słownika posiadają odpowiedni typ danych. Dzięki temu można je filtrować czy sortować.

Między słownikami mogą zachodzić relacje. W przykładowej paczce mamy 5 słowników i 3 relacje:
- kraje,
- miasta,
- chłopcy,
- dziewczyny,
- kategorie.
Miasto należy do kraju (1:n), chłopcy łączą się z dziewczętami w pary (m:n), a kategorie odnoszą się do samych siebie (drzewko 1:n).

Po utworzeniu słownika metodą build konieczne również jest ręczne utworzenie klasy modelu, który dziedziczy po klasie Dict_ORM. W klasie tej ręcznie definiujemy relacje (standardowo: $belongs_to, $has_many...). Metody modyfikujące obiekt słownika mają ten sam interfejs co dla zwykłych tabel. Przykładowo: możemy wywołać save(), delete(), add(), remove(). Metody te nie wpisują danych do tabeli słownika (może to być przecież widok), a przenoszą je do tabel modułu tak, by były poprawnie wyświetlane w dalszym etapie pracy. Możemy zatem spokojnie zrobić:
$polska = ORM::factory('country');
$polska->name = 'Polska';
$polska->save();


Z racji tego, że wszystkie wartości słownikowe przechowywane są w jednej tabeli (dict_definitions) istnieje prawdopodobieństwo przypisania wartości nie z tego słownika, o który nam chodzi. By dokonać walidacji poprawności słownika danej wartości można skorzystać z metody walidacji valid_dict::dict_index:
$validation = Validation::factory(array(
'def' => 1
));

$validation->add_rules('def', 'valid_dict::dict_index[city]');

var_dump($validation->validate());


Obsługa słowników w kodzie odbywa się analogicznie do pracy ze zwykłym ORM (metody z przykładowego kontrolera):
<?php
// W standardowej wersji Kohany trzeba wczytać ręcznie.
require_once Kohana::find_file('libraries', 'Dict/ORM');
// W standardowej wersji Kohany trzeba zainicjować obiekt Lang.
$lang = Lang::instance();

class Dict_Controller extends Controller {
public function index() {
url::redirect('dict/build');
}

// Budowa słowników
public function build() {
$mode = TRUE; // Słowniki jako tabele.
$mode = FALSE; // Słowniki jako widoki.
$mode = NULL; // Tryb ustalony na podstawie konfiguracji.

// Utworzenie wybranego słownika.
ORM::factory('dict_dictionary')->get_by_index('city')->build($mode);

// Utworzenie wszystkich słowników.
ORM::factory('dict_dictionary')->build_all($mode);
}

// Wyświetlenie słownika miejscowości (relacja 1:n).
public function country_city() {
// Wykorzystanie jak standardowy ORM!
$cities = ORM::factory('city')->find_all();

foreach ($cities as $city) {
// Obsługa relacji 1:n.
echo $city->name.' (kraj: '.$city->country->name.')<br />';
}

echo '<hr>';

// I w drugą stronę.
$countries = ORM::factory('country')->find_all();

foreach ($countries as $country) {
echo $country->name.'<br>';

foreach ($country->cities as $city) {
echo '- '.$city->name.'<br>';
}

echo '<br>';
}
//

echo '<hr>';

// Filtrowanie + sortowanie.
$cities = ORM::factory('city')
->where('population >', 15)
->orderby('name', 'DESC')
->find_all()
;

foreach ($cities as $city) {
echo $city->name.'<br>';
}
//
}

// Wyświetlenie słownika ludzi (relacja m:n).
public function boy_girl() {
$boys = ORM::factory('boy')->find_all();

foreach ($boys as $boy) {
echo $boy->name.'<br>';

// Obsługa relacji m:n.
foreach ($boy->girls as $girl) {
echo '- '.$girl->name.'<br>';
}

echo '<br>';
}
}

public function category() {
$categories = ORM::factory('category')
->where('parent_id IS', NULL)
->find_all()
;

$this->display_categories($categories);
}

private function display_categories($categories) {
echo '<ul>';

foreach ($categories as $category) {
echo '<li>';

echo $category->name;

$children = $category->children;

if (count($children) > 0) {
$this->display_categories($children);
}

echo '</li>';
}

echo '</ul>';
}

public function create() {
// Kraje.
$polska = ORM::factory('country');
$polska->name = 'Polska';
$polska->save();

$anglia = ORM::factory('country');
$anglia->name = 'Anglia';
$anglia->save();
//

// Miejscowości.
$sosnowiec = ORM::factory('city');
$sosnowiec->country_id = $polska->id;
$sosnowiec->name = 'Sosnowiec';
$sosnowiec->latitude = 10.5;
$sosnowiec->longitude = 50.1;
$sosnowiec->population = 15;
$sosnowiec->is_cool = 't';
$sosnowiec->last_date = date('Y-m-d');
$sosnowiec->last_time = date('H:i:s');
$sosnowiec->last_datetime = date('Y-m-d H:i:s');
$sosnowiec->save();

$dabrowa = ORM::factory('city');
$dabrowa->country_id = $polska->id;
$dabrowa->name = 'Dabrowa Gornicza';
$dabrowa->latitude = 33.3;
$dabrowa->longitude = 44.4;
$dabrowa->population = 20;
$dabrowa->is_cool = 't';
$dabrowa->last_date = date('Y-m-d');
$dabrowa->last_time = date('H:i:s');
$dabrowa->last_datetime = date('Y-m-d H:i:s');
$dabrowa->save();

$londyn = ORM::factory('city');
$londyn->country_id = $anglia->id;
$londyn->name = 'Londyn';
$londyn->latitude = 12;
$londyn->longitude = 21;
$londyn->population = 17;
$londyn->is_cool = 'f';
$londyn->last_date = date('Y-m-d');
$londyn->last_time = date('H:i:s');
$londyn->last_datetime = date('Y-m-d H:i:s');
$londyn->save();
//

// Chlopcy.
$mietek = ORM::factory('boy');
$mietek->name = 'Mietek';
$mietek->save();

$heniek = ORM::factory('boy');
$heniek->name = 'Heniek';
$heniek->save();
//

// Dziewczynki.
$miecia = ORM::factory('girl');
$miecia->name = 'Miecia';
$miecia->save();

$henia = ORM::factory('girl');
$henia->name = 'Henia';
$henia->save();
//

// Pary.
$mietek->add($miecia);
$mietek->save();

$heniek->add($miecia);
$heniek->add($henia);
$heniek->save();
//

// Kategorie.
$motoryzacja = ORM::factory('category');
$motoryzacja->name = 'Motoryzacja';
$motoryzacja->save();

$agd = ORM::factory('category');
$agd->name = 'AGD';
$agd->save();

$samochody = ORM::factory('category');
$samochody->parent_id = $motoryzacja->id;
$samochody->name = 'Samochody';
$samochody->save();

$motocykle = ORM::factory('category');
$motocykle->parent_id = $motoryzacja->id;
$motocykle->name = 'Motocykle';
$motocykle->save();

$osobowe = ORM::factory('category');
$osobowe->parent_id = $samochody->id;
$osobowe->name = 'Osobowe';
$osobowe->save();

$dostawcze = ORM::factory('category');
$dostawcze->parent_id = $samochody->id;
$dostawcze->name = 'Dostawcze';
$dostawcze->save();
//
}
}


To chyba tyle.

Demo:
http://kohana_2345.n...ct/country_city
http://kohana_2345.n...l/dict/boy_girl
http://kohana_2345.n...l/dict/category

Download: http://kohana_2345.n...ero.pl/dict.zip

W paczce znajduje się:
- dict - moduł,
- dict_extends - klasy dodatkowe (pobrane z Kohana 2.3.4.5),
- dict_examples - przykładowe dane (kontroler + modele + zrzut bazy danych).

PS: Nie mam przygotowanego mechanizmu zarządzania danymi słownikowymi w poziomu przeglądarki. Część administracyjna poczeka na stworzenie osobnego modułu do stawiania admina :)
Notifero - Technologie Informatyczne | Warsztat: Kohana 3.x/2.x + PostgreSQL/MySQL | Programista Kohana

#2 phpion

phpion

    Senior Mastah

  • Użytkownik
  • PipPipPip
  • 774 postów
  • Skąd:Sosnowiec, Dąbrowa Górnicza

Napisano 15 czerwiec 2012 - 12:24

Dodałem jeszcze obsługę drzewek z wykorzystaniem klasy ORM_Tree. W tym celu należy utworzyć relację 1:n między tym samym słownikiem.

Przykład działania:
http://kohana_2345.n...l/dict/category
Notifero - Technologie Informatyczne | Warsztat: Kohana 3.x/2.x + PostgreSQL/MySQL | Programista Kohana




Użytkownicy przeglądający ten temat: 0

0 użytkowników, 0 gości, 0 anonimowych