Component Development - Backend
MVC Explained
- MVC Explained: https://www.youtube.com/watch?v=DUg2SWWK18I
- Μόνο τα βίντεο 8, 9 και 10: https://www.youtube.com/watch?v=me5xLRcwL14&list=PLLi1ciqQAf8T_78YPUdMj5joE_kk1oomc&index=8
Εφαρμογή (Component)
Θα σου στείλω τα αρχεία μιας εφαρμογής. Την εγκαθιστάς να δεις πως δουλεύει. Μπορείς με καινούριο στοιχείο μενού να δείξεις ένα κομμάτι της εφαρμογής από το frontend που θέλουμε και μπορείς να προσθέσεις κάτι καινούριο από τη διαχείριση Εφαρμογές -> Test -> Items -> New
Δημιουργία Κατηγοριών (Categories)
Στο διαχειριστικό του component test simple:
- Στο αρχείο XML του component (π.χ. test.xml) προσθέτεις νέο submenu στοιχείο με όνομα "Categories" στην ενότητα administration, ώστε να εμφανίζεται στο backend μενού. Zip αρχείου και (ξανα)εγκατάσταση.
- Δημιουργείς στον πίνακα της βάσης (π.χ. phpmyadmin) έναν νέο πίνακα test_categories με πεδία id, name και με το σωστό πρόθεμα, κλπ., για να αποθηκεύεις τις κατηγορίες. Δημιουργία αντίστοιχου πίνακα στη βάση test_categories από το phpmyadmin με id, name τουλάχιστον.
- Αντιγραφή των μαρκαρισμένων αρχείων στην εικόνα και τα ονομάζουμε Category και Categories αντίστοιχα. Ό,τι βλέπουμε Item και Items εκτός από τις συναρτήσεις getItem και getItems καθώς και τις μεταβλητές $item / $items ή $this->item / $this->items που αφορούν σε κάθε MVC στο view κομμάτι - το item το αντικείμενο, απλά τυχαίνει να συμβαδίζει το όνομα item/προϊόν με το $item του MVC.
Σύνδεση Κατηγοριών με Items
Στη φόρμα item.xml προσθέτεις πεδίο τύπου sql που θα εμφανίζει όλες τις διαθέσιμες κατηγορίες. Το πεδίο προβάλλεται στο tmpl/item/edit.php μέσω renderField.
Αποθήκευση και Σύνδεση Κατηγοριών
Κατά την αποθήκευση μέσα στη μέθοδο save() του Model, μετά το parent::save(), αν η αποθήκευση είναι επιτυχής, ενημερώνεις ένα ξεχωριστό πίνακα many-to-many π.χ. items_categories με πεδία item_id και category_id, που συσχετίζει προϊόντα και κατηγορίες.
| item_id | category_id |
|---|---|
| 1 | 2 |
| 1 | 5 |
| 1 | 8 |
| 2 | 2 |
| 2 | 5 |
Ακόμη, ενημερώνεις τις μεθόδους getItem και save στο src/Model/ItemModel.php ώστε να διαχειρίζονται την αντιστοίχηση.
Κώδικας save - Αποθήκευση κατηγοριών
Στη save για να αποθηκεύσουμε τις κατηγορίες στον πίνακα items_categories:
// save item categories to items_categories table
$query = $db->getQuery(true);
$query->delete('#__test_item_categories')->where('item_id = '. $item->id);
$db->setQuery($query);
$db->execute();
foreach ($data['categories'] as $categoryId) {
$query = $db->getQuery(true);
$query->insert('#__test_item_categories')
->set(array(
('item_id = '. $item->id),
('category_id = '. intval($categoryId))
));
$db->setQuery($query);
$db->execute();
}
Κώδικας getItem - Φόρτωση κατηγοριών
Αν ορίσουμε π.χ. $item->categories = [1,2]; θα βλέπουμε μονίμως επιλεγμένες τις κατηγορίες με id 1 και 2 αλλά θα τα τραβάμε από τη βάση με τον παρακάτω τρόπο:
// load selected categories for item
$db = Factory::getDbo();
$query = $db->getQuery(true);
$query
->select('c.category_id')
->from('#__test_item_categories as c')
->where('c.item_id = '. intval($item->id));
$db->setQuery($query);
$item->categories = $db->loadColumn();
Το ίδιο κι αν ορίσεις $item->name = 'blabla'; θα δεις το όνομα να γίνεται "blabla" στο input πεδίο. Εφόσον το htmlView κάνει getItem και εκτυπώνεται μπροστά το $this->item->name μέσω του renderField που αυτό κάνει.
- https://docs.joomla.org/Inserting,_Updating_and_Removing_data_using_JDatabase
- https://docs.joomla.org/Selecting_data_using_JDatabase
Database Access
Στο model ισχύει το:
$db=$this->getDatabase();
Αλλιώς από άλλα σημεία που δεν χρειάζεται ακόμα είναι:
$db = Factory::getContainer()->get('DatabaseDriver');
Εμφάνιση κατηγοριών στη λίστα Items
Τώρα θα το κάνουμε και στη λίστα με τα items να φαίνονται μέσω της getListQuery και του tmpl/items/default.php. Εμφανίζεις άλλο ένα column στον πίνακα και βάζεις το th και tr αντίστοιχα με την πληροφορία των κατηγοριών.
Κάπως έτσι μέσα στη getListQuery:
// Subquery to get categories
$subQueryCategories = $db->getQuery(true)
->select('ca.item_id, GROUP_CONCAT(c.name SEPARATOR ", ") AS category_names')
->from('#__test_item_categories AS ca')
->join('LEFT', '#__test_categories AS c ON ca.category_id = c.id')
->group('ca.item_id');
$query->select('cat.category_names AS category_names')
->join('LEFT', '(' . $subQueryCategories . ') AS cat ON cat.item_id = a.id');
Για το διαχειριστικό πάντα μιλάμε - να φανεί και στη λίστα πριν μπούμε στο προϊόν σε ποιες κατηγορίες ανήκει.
Ανάλογη λογική μπορεί να ακολουθηθεί και για άλλες σχετικές οντότητες όπως manufacturers.
Αλλαγές στο Frontend & Δικαιώματα
- Αλλαγή εμφάνισης των items στο frontend (
<div class="items-list"><div class="item"> </div> </div>) - Εμφάνιση και στη λίστα (συνάρτηση getItems στο
src/Model/ItemsModel.php) - Δικαιώματα Χρηστών (Προσθήκη στο access.xml στον κεντρικό φάκελο, τα δικαιώματα που θέλουμε στο section component). Τα δικαιώματα τα διαχειριζόμαστε για τη κάθε ομάδα χρήστη από Σύστημα -> Γενικές Ρυθμίσεις -> Test -> Δικαιώματα
Έλεγχος δικαιωμάτων στον κώδικα
use Joomla\CMS\Helper\ContentHelper;
$canDo = ContentHelper::getActions('com_test');
if($canDo->get('to.name')){//στη get βάζουμε το name που έχουμε στο access.xml
}else{
}
Δημιούργησε έναν νέο χρήστη στο user group Administrator και άλλαξέ του τα δικαιώματα ώστε να δεις πως μπορείς να εκμεταλλευτείς αυτή τη λειτουργία.
ACL - Content Helper
https://manual.joomla.org/docs/general-concepts/acl/acl-permissions/
Κάνε ένα καινούριο χρήστη παράλληλα που να είναι administrator και πρόσθεσε permissions στην εφαρμογή μας μέσω του access.xml (administrator/components/com_dianemo/access.xml) το οποίο φορτώνεται μέσα στο config.xml. Στο config.xml μπορούμε να ορίζουμε γενικές ρυθμίσεις της εφαρμογής προσθέτοντας και εκεί πεδία.
Στις γενικές ρυθμίσεις της εφαρμογής πάμε από τις Γενικές Ρυθμίσεις και επιλέγουμε από τα αριστερά την εφαρμογή μας. Κρύψε ή εμφάνισε κάτι στο διαχειριστικό μόνο στον administrator. Αναλόγως τι ορίζεις εσύ στις γενικές ρυθμίσεις της εφαρμογής μας. Αν πούμε ο administrator να μπορεί να κάνει κάτι, το βλέπει. Αν το αλλάξουμε από το διαχειριστικό και του κόψουμε το δικαίωμα, δεν θα το βλέπει.
Ρυθμίσεις εφαρμογής
Για να πάρουμε κάποια ρύθμιση από την εφαρμογή μας:
$settings = ComponentHelper::getParams('com_test');
Μας επιστρέφει ένα πίνακα με τις γενικές ρυθμίσεις.
Έλεγχος δικαιώματος χρήστη
$allowed = $user->authorise('core.create', 'com_contact');
ή
use Joomla\CMS\Helper\ContentHelper;
$canDo = ContentHelper::getActions('com_example');
if ($canDo->get('core.create')) { // display New button}
if ($canDo->get('core.delete')) { // display Delete button} // etc
Και αντί για core.create κλπ βάζουμε το όνομα που έχουμε δώσει στο access.xml.
Πρέπει να φτιάξεις και έναν π.χ. administrator και να ελέγξεις όταν συνδέεσαι ότι όντως βλέπει κάτι διαφορετικό με μια if, αν είναι κουμπί / κάποια λειτουργία ή οτιδήποτε.
Batch
https://docs.joomla.org/J3.x:Developing_an_MVC_Component/Adding_a_batch_process
Κώδικας: code_2-acl-batch.zip
Popups Joomla Core
Joomla popup: https://docs.joomla.org/J4.x:Joomla_4_Tips_and_Tricks:_Modal_Box_Data