Joomla! İçin özel bir bileşen geliştiriyorum. 3.x ve bazı verileri almak için içinde AJAX araması yapmak istiyor. Bunu yapmanın doğru yolu nedir?
Joomla! İçin özel bir bileşen geliştiriyorum. 3.x ve bazı verileri almak için içinde AJAX araması yapmak istiyor. Bunu yapmanın doğru yolu nedir?
Yanıtlar:
LÜTFEN BU CEVAP LÜTFEN zaten birkaç yaşında ve güncellenmedi. Bir şeyin artık kesin olmadığını düşünüyorsanız, düzenlemek / yorum yapmaktan çekinmeyin.
Bununla baş etmek için neredeyse hiçbir resmi yol yok, bu çok karmaşıklığa ve işi yapmak için MVC modeline ne kadar güvenmek istediğinize bağlı.
Aşağıda Joomla 2.5 ve 3.x'de çalışması gereken bazı olası çözümler bulunmaktadır. Kod, kopyala ve yapıştır işinde sunulmaz, genel bir fikir olarak sunulur.
Joomla! 3.2 Aşağıdaki örnekleri kullanmanız gereken tek şey a component
. Joomla 3.2'den sonra (daha düşük karmaşık işler için) isteği modüller ve eklentilerden alabilirsiniz.
Sizin URL görev için böyle bir görünüm gerekir:
index.php?option=com_similar&task=abc&format=raw
Abc
View.raw.html (normal bir görüntüleme dosyasıyla aynı) dosyasını içerecek olan görünümü kullanacak olan denetleyiciyi oluşturmaktan çok diyelim .
Ham bir HTML yanıtı oluşturmak için kodunuzun altında:
/controller.php
public function abc()
{
// Set view
// Joomla 2.5
JRequest::setVar('view', 'Abc');
// (use JInput in 3.x)
$this->input->set('view', 'Abc');
parent::display();
}
/views/abc/view.raw.php
<?php
defined('_JEXEC') or die;
jimport('joomla.application.component.view');
class SimilarViewAbc extends JViewLegacy
{
function display($tpl = null)
{
parent::display($tpl);
}
}
/views/abc/tmpl/default.php
<?php
echo "Hello World from /views/abc/tmpl/default.php";
Not: HTML'yi döndürmek zorunda kalsam kullanacağım çözüm budur (daha temiz ve Joomla mantığını izler). Basit JSON verilerini döndürmek için, her şeyi kontrol ünitesine nasıl koyacağınıza bakınız.
Ajax isteğinizi bir alt denetleyiciye yaparsanız , aşağıdaki gibi:
index.php?option=com_similar&controller=abc&format=raw
Alt denetleyicinizin adından (işlenmemiş görünüm için) olması gerekir abc.raw.php
.
Bu aynı zamanda Abc adında 2 alt denetleyiciye sahip olabileceğiniz / olabileceğiniz anlamına gelir.
Eğer JSON dönerseniz, kullanımı mantıklı olabilir format=json
ve abc.json.php
. Joomla 2.5'te. Bu seçeneğin çalışması için bazı sorunlar yaşadım (bir şekilde çıktı bozuldu), bu yüzden ham kullandım.
Geçerli bir JSON yanıtı oluşturmanız gerekiyorsa , JSON çıktısını oluşturma belgesini inceleyin.
// We assume that the whatver you do was a success.
$response = array("success" => true);
// You can also return something like:
$response = array("success" => false, "error"=> "Could not find ...");
// Get the document object.
$document = JFactory::getDocument();
// Set the MIME type for JSON output.
$document->setMimeEncoding('application/json');
// Change the suggested filename.
JResponse::setHeader('Content-Disposition','attachment;filename="result.json"');
echo json_encode($response);
Bu kodu genellikle denetleyiciye koyarsınız (kodladığınız verileri döndürecek bir model arayacaksınız - çok yaygın bir senaryo). Daha ileri gitmeniz gerekiyorsa, ham örneğe benzer bir JSON görünümü de (view.json.php) oluşturabilirsiniz.
Şimdi Ajax isteği çalışıyor, henüz sayfayı kapatmayın. Alttarafı oku.
Sahtecilik talebini kontrol etmeyi unutma. JSession::checkToken()
burada işe yarayacak. CSRF anti-spoofing forma ekleme hakkında belgeleri okuyun.
İstekte dil adını göndermezseniz, Joomla istediğiniz dil dizelerini çevirmez.
İsteğinize bir şekilde lang paramını eklemeyi düşünün (gibi &lang=de
).
Joomla 3.2'deki Yenilikler! - bir bileşen oluşturmadan işlem istekleri yapmanızı sağlar
Joomla! Ajax Arabirimi - Joomla artık bir eklenti veya modülde Ajax isteğini yerine getirmenin hafif bir yolunu sunuyor. Joomla !'yı kullanmak isteyebilirsiniz. Ajax Arayüzü, eğer zaten bir bileşeniniz yoksa veya sahip olduğunuz bir modülden istekte bulunmanız gerekiyorsa.
JRequest
? $this->input
V3.x kullandığımdan beri öyle olmalı mı?
JRequest
. Teşekkürler
Valid JSON Response
bölümde bahsetti .
Bu çok iyi cevaplanmış bir soru için geç bir cevap, ancak bir AJAX çağrısı ile bileşenlerinin verilerine ulaşmak için basit bir yol arayanlar için bu kısaltmaya hazır çözümü eklemek istedim.
Tüm Joomla sürümleri, 3. parti olanakları ve birkaç gün süren googling ile ilgili bulduğum hack'lerle, bulabildiğim en basit yaklaşım buydu - ve geri bildirimler kesinlikle takdir edildi.
execute
Mevcut ana denetleyicime işlev eklendiGörevi aramak / yürütmek için URL:
www.mysite.com/index.php?option=com_example&task=ForAjax.mytaskname
Değiştirilmiş Ana Denetleyici \ com_example \ controller.php
class ExampleController extends JControllerLegacy {
public function display($cachable = false, $urlparams = false) {
$app = JFactory::getApplication();
$view = $app->input->getCmd('view', 'default');
$app->input->set('view', $view);
parent::display($cachable, $urlparams);
return $this;
}
public function execute()
{
// Not technically needed, but a DAMN good idea. See http://docs.joomla.org/How_to_add_CSRF_anti-spoofing_to_forms
// JSession::checkToken();
$task = JFactory::getApplication()->input->get('task');
try
{
parent::execute($task);
}
catch(Exception $e)
{
echo new JResponseJson($e);
}
}
}
Yeni Alt Denetleyici \ com_example \ controllers \ forajax.php
require_once JPATH_COMPONENT.'/controller.php';
class ExampleControllerForAjax extends ExampleController
{
public function MyTaskName()
{
$app = JFactory::getApplication();
$data['myRequest'] =$_REQUEST;
$data['myFile'] =__FILE__;
$data['myLine'] ='Line '.__LINE__;
$app->enqueueMessage('This part was reached at line ' . __LINE__);
$app->enqueueMessage('Then this part was reached at line ' . __LINE__);
$app->enqueueMessage('Here was a small warning at line ' . __LINE__, 'warning');
$app->enqueueMessage('Here was a big warning at line ' . __LINE__, 'error');
$task_failed = false;
echo new JResponseJson($data, 'My main response message',$task_failed);
$app->close();
}
}
Render JSON Çıkışı
{
success: true,
message: "My main response message",
messages: {
message: [
"This part was reached at line 26",
"Then this part was reached at line 27"
],
warning: [
"Here was a small warning at line 28"
],
error: [
"Here was a big warning at line 29"
]
},
data: {
myRequest: {
option: "com_example",
task: "mytaskname",
Itemid: null
},
myFile: "C:\mysite\components\com_example\controllers\forajax.php",
myLine: "Line 24"
}
}
Valentin cevabı iyidir, ancak yapmanız gereken tek şey hali hazırda inşa edilmiş bir bileşene 1 veya 2 ajax çağrısı eklemekse, biraz fazla karmaşıktır. Ayrı controller.raw.php
veya view.raw.php
dosya yapmadan kurtulmak mükemmel bir şekilde mümkün .
Ajax araması yapmak için
index.php?format=raw&option=com_example&controller=job&task=keep_alive&tokenhash=1
Alt job
kontrolörde
public function keep_alive() {
$this->ajax_check();
//Do your processing and echo out whatever you want to return to the AJAX call
header('HTTP/1.1 202 Accepted', true, 202);
echo 'OK';
JFactory::getApplication()->close();
}
// Verifies jtoken and does a basic check that this is actually an AJAX call
private function ajax_check() {
if(!JSession::checkToken('GET') || !isset($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest') {
header('HTTP/1.1 403 Forbidden', true, 403);
JFactory::getApplication()->close();
}
}
Valentin'in cevabı iyidir.
Bir json temel sınıfı oluşturduğum için kodlama ve hata işlemeyi yapan bir json denetleyicisini tercih ediyorum:
class itrControllerJson extends JControllerLegacy {
/** @var array the response to the client */
protected $response = array();
public function addResponse($type, $message, $status=200) {
array_push($this->response, array(
'status' => $status,
'type' => $type,
'data' => $message
));
}
/**
* Outputs the response
* @return JControllerLegacy|void
*/
public function display() {
$response = array(
'status' => 200,
'type' => 'multiple',
'count' => count($this->response),
'messages' => $this->response
);
echo json_encode($response);
jexit();
}
}
Bu denetleyici, işi yapan denetleyici sınıfı tarafından genişletilir:
require_once __DIR__.'json.php';
class componentControllerAddress extends itrControllerJson {
public function get() {
try {
if (!JSession::checkToken()) {
throw new Exception(JText::_('JINVALID_TOKEN'), 500);
}
$app = JFactory::getApplication();
$id = $app->input->get('id', null, 'uint');
if (is_null($id)) {
throw new Exception('Invalid Parameter', 500);
}
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('*');
$query->from('#__table');
$query->where('id = '.$db->quote($id));
$db->setQuery($query);
$response = $db->loadObject();
$this->addResponse('message', $response, 200);
} catch (Exception $e) {
$this->addResponse('error', $e->getMessage(), 500);
}
$this->display();
}
}
ve sen buna benzer bir istek diyorsun:
index.php?option=com_component&task=address.get&format=json&id=1234&tokenhash=1
Belirteç karma JSession :: getFormToken () tarafından üretilir. Yani tam arama aşağıdaki gibi görünebilir:
$link = JRoute::_('index.php?option=com_component&task=address.get&format=json&id=1234&'.JSession::getFormToken().'=1', false);
İkinci parametre "false" olarak ayarlanmıştır, bu yüzden bunu xml rewrite olmadan javascript çağrılarında kullanabiliriz.
JResponseJson
sınıfı idare etmek için kullanmıyorsun ?
Herhangi bir Javascript çıktısı ekleyen hiçbir üçüncü taraf eklentisi olmadığından% 100 eminseniz, saf bir json_encode çalışır.
Ancak ... örneğin JomSocial tüm siteye "" ekler.
Yani ... kullanışlı bir numara, json_encode'u etiketlerle sarın ve Javascript tarafında işleyin.
echo '@START@' . json_encode(...) . '@END@';
Görevdeki denetleyici adını kullanarak doğrudan denetleyiciye erişebilirsiniz:
index.php?option=com_similar&task=controller.abc&format=raw
arayacak: controller.raw.php (dönüş ham)
index.php?option=com_similar&task=controller.abc
arayacak: controller.php (eğer kullanmazsanız return html olur die;
)