PDA

Zobacz pełną wersję : Automatyczne tworzenie pozycji menu



TheNutpl
12-04-2016, 13:31
Witajcie,
Jestem w trakcie budowania komponentu. Tworzę go (niestety) w metodą CPE (copy-past-edit) w oparciu o inny gotowy komponent. Chciałem sobie uprościć życie i dodać opcje automatycznego tworzenia pozycji menu.
Proces wygląda następująco:
- komponent zawiera parametr umożliwiający wybranie typ menu dla tego komponentu (nie chcę, żeby pozycje były w main menu)

Podczas dodawania nowego elementu w komponencie:
1. Sprawdzanie czy parametr został ustalony.
2. Jeśli NIE: dodawanie nowego menu do tabeli #__menu_types oraz aktualizacja parametru komponentu. | Jeśli TAK: -
3. Sprawdzanie czy w danym menu istnieje pozycja, która spełnia warunek menu.alias == components.emelent.alias
4. Jeśli NIE: dodawanie do tabeli (#__menu) nowej pozycji | Jeśli TAK: aktualizacja istniejącej pozycji, aby była połączona z nowym elementem.

Cała ta funkcjonalność działa poprawnie od strony technicznej. Pobieranie, aktualizowanie i dodawanie rekordów do table działa w 100%. Niestety po dodaniu pozycji menu, nie jest ona widoczna. Nie ma jej w żadnym menu, mimo, że jest opublikowana i włączona (a nie np usunięta do kosza).

Czy istnieje jakiś łatwy, zdefioniowany sposób na dodanie pozycji menu, albo jak wygląda proces dodawania pozycji menu? Może pomijam jakąś tabelę, albo muszę zaktualizować jakiś rekord.

Dzięki

zwiastun
12-04-2016, 14:23
Czy uwzględniłeś tabelę content_types (definiuje typy zawartości)?

TheNutpl
12-04-2016, 15:29
Nie, ale już znalazłem o wiele prostsze rozwiązanie:



jimport('joomla.application.component.helper');
$params = JComponentHelper::getParams('com_sample');
$menuType= $params->get('menuType');

$comp = JComponentHelper::getComponent('com_sample');
$comId= $comp->id;

$link = 'index.php?option=com_sample&view=test&id=';
$link .= $this->id;

$menuTable = JTableNested::getInstance('Menu');

$menuData = array(
'menutype' => $menuType,
'title' => $this->title,
'alias' => $this->alias,
'path' => $this->alias,
'link' => $link,
'type' => 'component',
'component_id' => $comId,
'language' => '*',
'published' => 1,
'access' => 1,
);

// this item is at the root so the parent id needs to be 1
$parent_id = 1;
$menuTable->setLocation($parent_id, 'last-child');

// save is the shortcut method for bind, check and store
if (!$menuTable->save($menuData))
{
$this->setError($menuTable->getError());
return false;
}

Problemem może być pobranie ID elementu na poziomie tworzenia go, ale w mojej głowie tworzą się dwa rozwiązania:
1) jeśli mamy pewność, że do strona nie będzie obsługiwana przez duża ilość użytkowników, przez co nie będzie możliwości dodawania dwóch elementów przez dwóch różnych administratorów w tym samym czasie, to można pobrać MAX(id) z tabeli komponentu i powiększyć go o 1. Aby nie było problemów z opcją auto-increment w MySQL, należałoby od razu zdefiniować id elementu.

2) w widoku dodawania pojedynczego elementu (załóżmy test) zastosować ten skrypt. Wtedy przy zapisie tworzona byłaby pozycja menu z linkiem w postaci index.php?option=com_sample&view=test&id=0
Następnie w widoku test i tests zastosowac skrypt, który pobbrałby wszystkie elementy z menu, które spełniają warunek link = index.php?option=com_sample&view=test&id=0 i zaktualiwoać wartości o odpowiednie id.

Owszem, w obu przypadkach nie jest to doskonałe rozwiązanie i nie będzie działało w 100%, ale będą spełniały swoje funkcje.

zwiastun
12-04-2016, 16:19
Tu Ci niewiele pomogę. Natomiast myślę, że warto jeszcze zwrócić Twoją uwagę na niestandardowość akcji, którą chcesz zaimplementować i w związku z tym poddać pod rozwagę użyteczność takiego rozwiązania.
Projektanci i administratorzy Joomla wiedzą, jak się tworzy pozycje menu. W dawnych wersjach (Mambo, Joomla 1.0) była możliwość utworzenia "automatycznie" pozycji menu (wymagało to, oczywiście, wywołania akcji w komponencie przez administratora). Z takiego rozwiązania zrezygnowano już dawno jako mało użytecznego (użyteczność to nie tylko cecha polegająca na tym, że jakaś funkcjonalność jest przydatna, to także kwestii a tego, jak się tę funkcjonalność realizuje w systemie).
Jakie masz uzasadnienie dla odchodzenia od standardu? Jakie będą koszty takiego odejścia (użytkowników trzeba uczyć, że jest inaczej niż w innych komponentach - to jest koszt; inne rozwiązanie niż standardowe może powodować szereg innych konsekwencji w systemie - konieczność innych niestandardowych akcji).
Przemyśl to.

TheNutpl
12-04-2016, 16:52
Problem leży w tym, że komponent, który ma na wzór wyrzuca link do pojedynczego elementu w postaci domena.com/1.htm?view=test
Zależy mi na tym, żeby link był oparty o aliasie (coś wstylu domena.com/to-jest-test.html)
Próbowałem zmienić to na bazie innego komponentu, ale nie dałem rady. Tak to jest jak się przerabia kod, a nie tworzy. Dlatego wpadłem na ten pomysł. Generalnie zaplecze bedzie obsługiwane przez jednego lub dwóch adminów, więc za dużo "strat" nie będzie, z kolei rozwiąże to moje problemy z routingiem.

k@m!l
15-04-2016, 22:11
Po pierwsze: https://docs.joomla.org/Supporting_SEF_URLs_in_your_component
Po drugie: przejrzyj sobie plik router.php choćby z com_content.
Po trzecie: wydaje mi się że za bardzo kombinujesz. Nie wiem czy dobrze Cię zrozumiałem, ale może w konfiguracji komponentu dodaj pole, w którym wybiera się bazową pozycję menu do której są dodawane kolejne podelementy.