Có thể buộc móc cập nhật mô-đun của bạn chạy không?


18

Tôi là tác giả của mô-đun Date iCal và phiên bản chính mới mà tôi đang làm việc (3.x) yêu cầu cập nhật lược đồ hai phần cho người dùng đã cài đặt 2.x. Tôi đã viết móc cập nhật tạo ra những thay đổi này, nhưng nếu một trong những người dùng của tôi không chạy tập lệnh cập nhật cơ sở dữ liệu, họ sẽ nhận được thông báo lỗi liên quan đến nhà nhập khẩu nguồn cấp dữ liệu iCal của họ.

Giải pháp phù hợp là cho họ chạy tập lệnh cập nhật ... nhưng nếu họ chỉ vào và thay đổi thủ công trình nhập của mình để thoát khỏi thông báo, thì trình nhập của họ sẽ bị hỏng vĩnh viễn (vì phần thứ hai của bản cập nhật lược đồ sẽ không đã được thực hiện).

Vậy có cách nào để hiển thị thông báo cho người dùng chưa chạy bản cập nhật không? Hoặc bằng cách nào đó buộc thực hiện hook cập nhật lần đầu tiên khi tải trang xảy ra khi 3.x được cài đặt vượt quá 2.x?


2
Tôi sẽ tưởng tượng bạn có thể thực hiện variable_set()chức năng cập nhật của mình để đặt biến khi nó được chạy thành công mà bạn có thể nhìn vào bên trong _preprocess_page()nhưng bạn sẽ nhìn vào nó mỗi lần nên không chắc chắn mức độ thân thiện với hiệu suất này.
Jimajamma

Câu trả lời:


4

mở rộng về nhận xét từ Jimajamma:

thực hiện một variable_set()chức năng cập nhật của bạn để đặt một biến khi nó được chạy thành công mà bạn có thể nhìn vào bên trong một _pre process_page ()

và thay vì kiểm tra điều này trên mỗi lần tải trang, chỉ thực hiện khi duyệt khu vực quản trị và nếu phiên bản đã cài đặt là 3.0 (3.1, 3.2, hãy kiểm tra xem bạn có ngừng hỗ trợ phiên bản cũ làm đường dẫn nâng cấp không).

Ngoài ra, hãy sử dụng hook_Vquirements để cung cấp phản hồi trên trang báo cáo trạng thái:

Kiểm tra các yêu cầu cài đặt và làm báo cáo trạng thái.
(...)
Giai đoạn 'thời gian chạy' không giới hạn ở các yêu cầu cài đặt thuần túy nhưng cũng có thể được sử dụng cho thông tin trạng thái chung hơn như nhiệm vụ bảo trì và các vấn đề bảo mật.


15

Có một số cách buộc cập nhật mô-đun.

  1. Gọi chức năng cập nhật trực tiếp.

    $sandbox = [];
    module_load_include('install', 'FOO');
    FOO_update_7001($sandbox);
  2. Đặt lại phiên bản lược đồ đến điểm ưa thích và chạy lại các bản cập nhật như bình thường.

    drupal_set_installed_schema_version('module_name', '7000');

    Hoặc đặt lại để chỉ chạy lại lược đồ cập nhật mới nhất:

    drupal_set_installed_schema_version('foo', drupal_get_installed_schema_version('foo') - 1);

    Ghi chú:

    • Điều này có thể được đặt vào hook_install, vì vậy trong quá trình cập nhật, tất cả các móc cập nhật tuần tự sẽ được thực thi.
    • Để sử dụng chức năng này bên ngoài tệp cài đặt, install.inctrước tiên bạn phải bao gồm Drupal và tệp cài đặt của mô-đun, ví dụ:

      require_once DRUPAL_ROOT . '/includes/install.inc';
      module_load_include('install', 'foo');
    • Xem xét thêm ini_set('max_execution_time', 0);để cập nhật cài đặt lâu hơn để ngăn chặn thời gian chờ PHP.
  3. Sử dụng drush. Tìm một vài ví dụ dưới đây:

    • drush eval 'module_load_include('install', 'foo'); $s = []; foo_update_7001($s);'
    • drush sqlq "UPDATE system SET schema_version = 7000 WHERE name = 'foo'" && drush -y updb

1
Ồ tốt đẹp, tôi đã không biết về drupal_set_installed_schema_version(). Đó là siêu tiện dụng để gỡ lỗi móc cập nhật!
coredumperror

1
Vì vậy, vấn đề chính với việc đưa nó vào hook_install()là chạy các bản cập nhật theo đợt (hộp cát) dài. Trong tình huống lý tưởng, cần có một cách để kích hoạt các cập nhật theo cách tương tự như update.phpkhởi động lại luồng PHP để ngăn chặn thời gian chờ. Ant ý tưởng làm thế nào để làm điều đó?
Alex Skrypnyk

@ Alex.Designworks Bạn có thể thêm ini_set('max_execution_time', 0);trước khi kích hoạt các bản cập nhật.
kenorb

1

(Phần thưởng thành một câu trả lời)

Bạn có thể "CHỌN lược đồ_version TỪ hệ thống" để phát hiện xem bản cập nhật đã được thực hiện chưa. Nếu không, sau đó từ chối chạy (với một thông báo lỗi).


Vui lòng sắp xếp lại câu trả lời của bạn và cố gắng đưa ra một ví dụ sử dụng.
ЕЕннн

Bỏ qua bình luận này.
coredumperror

Tôi sợ rằng nó sẽ không hoạt động, bởi vì chức năng được đề cập là một plugin cho một mô-đun khác và tôi không thể ngăn mô-đun đó cho phép người dùng gây rối với nhà nhập khẩu của họ.
coredumperror

Bạn không thể kiểm tra phiên bản lược đồ của mô-đun mà bạn định theo dõi để cập nhật?
user18099

0

Tôi đồng ý với các đề xuất ở trên - bổ sung duy nhất của tôi sẽ là điều tra "Kích hoạt và hành động" - có vẻ như bạn cần một hành động (thông báo cho người dùng hoặc chạy cập nhật) xảy ra khi kích hoạt (người dùng kiểm tra trang quản trị, v.v.) . Đối với các ví dụ sử dụng, xem mô-đun Ví dụ, có cả mã ví dụ kích hoạt và hành động. :)


0

function MYMODULE_install() { $functions = get_defined_functions(); foreach ($functions['user'] as $function) { if (strpos($function, 'MYMODULE_update_') === 0) { call_user_func($function); } } }

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.