Skip to main content

Component Development - Backend

MVC Explained

Εφαρμογή (Component)

Θα σου στείλω τα αρχεία μιας εφαρμογής. Την εγκαθιστάς να δεις πως δουλεύει. Μπορείς με καινούριο στοιχείο μενού να δείξεις ένα κομμάτι της εφαρμογής από το frontend που θέλουμε και μπορείς να προσθέσεις κάτι καινούριο από τη διαχείριση Εφαρμογές -> Test -> Items -> New

Δημιουργία Κατηγοριών (Categories)

Στο διαχειριστικό του component test simple:

  1. Στο αρχείο XML του component (π.χ. test.xml) προσθέτεις νέο submenu στοιχείο με όνομα "Categories" στην ενότητα administration, ώστε να εμφανίζεται στο backend μενού. Zip αρχείου και (ξανα)εγκατάσταση.
  2. Δημιουργείς στον πίνακα της βάσης (π.χ. phpmyadmin) έναν νέο πίνακα test_categories με πεδία id, name και με το σωστό πρόθεμα, κλπ., για να αποθηκεύεις τις κατηγορίες. Δημιουργία αντίστοιχου πίνακα στη βάση test_categories από το phpmyadmin με id, name τουλάχιστον.
  3. Αντιγραφή των μαρκαρισμένων αρχείων στην εικόνα και τα ονομάζουμε 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_idcategory_id
12
15
18
22
25

Ακόμη, ενημερώνεις τις μεθόδους 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 που αυτό κάνει.

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