it-swarm-vi.com

Joomla 2.5 khác biệt về JFormField từ 3.x

Tôi đã và đang sử dụng một plugin để giúp thêm các tham số bổ sung cho các mô-đun, để làm điều đó tôi sử dụng JForm để tải một tệp xml được bao gồm nhiều plugin khác nhau.

Đây là những gì tôi đã và đang sử dụng và nó hoạt động trong 3.0 trở lên, nó được tạo thành một vòng lặp fieldset và mỗi "trường" là một thể hiện của JFormField.

$field->name = 'plg_form_settings['.$field->name.']';
$content .= '<div class="control-group">';
    $content .= '<div class="control-label">';
        $content .= $field->label;
    $content .= '</div>';
    $content .= '<div class="controls">';
        $content .= $field->input;
    $content .= '</div>';
$content .= '</div>';

Như bạn có thể thấy nó hoạt động với giả định rằng $field->name Là công khai, tuy nhiên trong 2.5 nó được bảo vệ (nó cũng ở trong 3 điều gây trở ngại cho tôi, nó không bao giờ hoạt động trong bất kỳ phiên bản 3 nào).

Tôi đã kiểm tra sự khác biệt giữa JFormField trong 2.5 và 3 và có sự khác biệt lớn, dù bằng cách này hay cách khác tôi cần truy cập vào thuộc tính $field->name (Tôi thấy tôi có thể thực hiện $field->__get('name') để truy cập chỉ đọc), tôi có thể bỏ qua chức năng của JFormField nhưng điều đó có vẻ hơi phản tác dụng để thêm khả năng tương thích ngược.

Trong Joomla 3 có một hàm gọi là __set($name,$value) tuy nhiên nó không có trong Joomla 2.5

Có cách nào "đơn giản" để ghi đè tên trường (hoặc thuộc tính khác) trong Joomla 2.5 không?

5
Jordan Ramstad

Tôi đã làm việc chăm chỉ về vấn đề này và đưa ra một giải pháp, đó là cách "phù hợp" để làm điều đó mà các mô-đun khác làm nhưng bị ẩn đằng sau nhiều lớp đối tượng (vì vậy hơi khó để tìm ra).

Đầu tiên tôi nghĩ rằng vấn đề là ở JFormField nhưng thực sự không phải vậy. Không cần truy cập vào các thuộc tính đó vì chúng chỉ "phân tích" các trường không được thực hiện để đưa ra bất kỳ kiểm soát trực tiếp nào.

Vì vậy, đây là một chút mã khác tôi có.

if($form->loadFile($path.'/fields.xml')){
        $fieldset = $form->getFieldset();
        //SQL STUFF HERE TO GET $result
        $result = $db->loadObject();
        if(isset($result->params)){
            $moduleParams = json_decode($result->params);
        }else{
            $moduleParams = new stdClass;
        }
        foreach($fieldset as $index=>$field){
            $field->name = 'plg_form_settings['.$field->name.']';
            $content .= '<div class="control-group">';
                $content .= '<div class="control-label">';
                    $content .= $field->label;
                $content .= '</div>';
                $content .= '<div class="controls">';
                    $content .= $field->input;
                $content .= '</div>';
            $content .= '</div>';
        }
    }

Điều này lặp lại từng trường trong bộ trường và trả về một thể hiện của JFormField một lớp chỉ đọc ít nhiều. Điều cần làm là mọi chỉnh sửa bạn muốn thực hiện đều được thực hiện thông qua chính JForm.

if($form->loadFile($path.'/fields.xml')){
    $fieldset = $form->getFieldset();
    //SQL STUFF HERE TO GET $result
    $result = $db->loadObject();
    if(isset($result->params)){
        $moduleParams = json_decode($result->params);
    }else{
        $moduleParams = new stdClass;
    }
    $dataArray = array();
    //split the loop into 2, this way the data can be bound
    foreach($fieldset as $index=>$field){
        if($id!=0&&isset($moduleParams->{$index})){
            $dataArray[$index] = $moduleParams->{$index};
        }
    }
    //bind and reset to ensure it worked
    $form->bind($dataArray);
    $fieldset = $form->getFieldset();
    foreach($fieldset as $index=>$field){
        $output = '<div class="control-group">';
            $output .= '<div class="control-label">';
                $output .= $field->label;
            $output .= '</div>';
            $output .= '<div class="controls">';
                $output .= $field->input;
            $output .= '</div>';
        $output .= '</div>';
        $content .= $output;
    }
}

Như bạn có thể thấy tôi sử dụng 2 vòng lặp, một vòng chỉ để khớp một tham số với một trường (tôi có thể cải thiện nó bằng cách lặp đối tượng $ moduleParams thực tế). Trong khi cái kia giống như cái tôi đã có trước đây. Ở giữa tôi liên kết dữ liệu để tạo và "đặt lại" biến fieldset (không chắc nó có cần hay không nhưng nó không bị tổn thương trong quá trình gỡ lỗi. Tuy nhiên, điều này sẽ chỉ thay đổi chính xác $field->value vì bạn đang ràng buộc một giá trị biểu mẫu, vì vậy các biến khác vẫn được bảo vệ.

Vì vậy, tôi đã đưa ra một giải pháp cho tên, mà câu hỏi này chủ yếu là về. JForm khá nghiêm ngặt về tên vì nó sử dụng nó làm cơ sở cho sự tương tác của nó với các đối tượng khác, vì vậy tốt nhất không nên chạm vào nó trong khi JForm đang phân tích cú pháp biểu mẫu, nhưng sau đó.

Hàm tôi đã hiển thị là một phần của "người trợ giúp" vì vậy tôi đã chuyển cái này ra ngoài nó và vào chính plugin. Vì tôi đang tạo một chuỗi html, tôi có thể sử dụng regex để tìm/thay thế.

$regex  = '/(?:name=")([^"]*)(?:")/';
//CALL HELPER TO GET $content
$content = '<input type="text" name="cc_field"/>'; //example of part of output from helper
$content = preg_replace($regex,"name=\"cc_settings[$1]\"",$content);

Điều này cũng sẽ cho phép bạn thay đổi tên, bên ngoài các vấn đề có thể gây ra bằng cách chỉnh sửa tên trong khi đối tượng JForm đang phân tích cú pháp các trường.

1
Jordan Ramstad