نواة SPIP مشتركة لعدة مواقع

عملية توزيع نواة SPIP على عدة مواقع

صار جعل نواة SPIP مشترك بين عدة مواقع ممكناً منذ SPIP ١.٩. والهدف هو امكان ادارة عدة مواقع في جهاز خدمة واحد او مضيف واحد باستخدام ملفات نواة SPIP مرة واحدة فقط وليس تثبيت كامل النظام في كل موقع.

وتتيح هذه الميزة توفير كبير في مساحة القرص الثابت في جهاز الخدمة كما تسهّل عملية تحديث النظام اذ لا تتم الا مرة واحدة.

المعروف ان الاصدار SPIP 1.9.1 سهّل هذه العملية ولكن اطلاق SPIP 1.9.2 مع كل تحسيناته [1] جعل هذه العملية اكثر متانة.

ويوضح هذا المقال العملية باستخدام SPIP 1.9.2 على خادم أباشي [2] يدعم اعادة كتابة عناوين URL (اي url_rewriting).

هناك عدة اساليب تؤدي الى النتيجة نفسها، منها ما يتعلق بإعداد التوزيع مباشرة من الموقع ومنها ما يتكفل بجهاز الخدمة.

المفهوم

من SPIP 1.9.2 اصبحت المجلدات الضرورية لتشغيل نواة SPIP (اي ecrire وsquelettes-dist وoo) والمجلدات التي تتحكم بنشاط الموقع (config وIMG وtmp وlocal) واضحة ومميزة ومنفصلة. وهذا الفصل هو الذي يسمح بوجود عدة مواقع SPIP مستقلة تديرها نواة واحدة.

ويعتمد هذا الاستقلال على وجود اربع مجلدات في كل موقع يسجل فيها SPIP البيانات الناتجة عن نشاط الموقع. ويبلغ عدد هذه المجلدات اربعة للتمييز بين البيانات الموقتة والدائمة من جهة والبيانات التي يمكن الوصول اليها من خلال http وتلك التي لا يمكن الوصول اليها من جهة اخرى. اما المجلدان اللذان لا يمكن الوصول اليهما بواسطة http، فهما محميان بملف htaccess. يثبته SPIP آلياً (يمكن لمدراء الموقع وضع المجلدين خارج هرمية المجلدات التي يصل اليها http).

قبل SPIP 1.9.2، لم تكن هذه الانواع الاربع من البيانات مميزة عن بعضها وكانت موجودة في مجلدات IMG وCACHE وecrire/data. ولكن مع SPIP 1.9.2 اصبحت هذه المجلدات الاربعة مميزة عن بعضها ومعرّفة بثوابت PHP التالية:

define('_NOM_TEMPORAIRES_INACCESSIBLES', "tmp/");
define('_NOM_TEMPORAIRES_ACCESSIBLES', "local/");
define('_NOM_PERMANENTS_INACCESSIBLES', "config/");
define('_NOM_PERMANENTS_ACCESSIBLES', "IMG/");

واذا كان SPIP غير مشتركاً يتم انشاء هذه المجلدات في اصل الموقع لدي تطبيق دالة spip_initialisation على القيم الاربع السابقة. وللحصول على توزيع نواة SPIP يكفي ربط عنوان URL معين بمجوعة رباعية معينة من المجلدات، وذلك بنداء دالة spip_initialisation لتطبيقها على اربع قيمخ اخرى مستنتجة من عنوان URL.

إنشاء المجلدات الصحيحة

لتشغيل توزيع النواة، يجب اولاً الانطلاق من موقع حقيقي. في مثالنا، سننطلق من موقع عنوانه /http://exemple.org مخزن في /home/myuser/public_html/.

يجب انشاء مجلد (اسمه «sites» مثلاً) سيجتوي مجلدات المواقع التي ستتشارك في النواة وسيكون هذا المجلد في الاصل (اي في المستوى الموجود فيه مجلد ecrire/.

 توزيع مجلد:
اذا اردنا ان ينادي كل العنوانين /http://exemple.org/first_site و/http://exemple.org/second_site مثلاً موقع SPIP مختلفاً، يجب انشاء المجلدين الفرعيين first_site/ وsecond_site/ داخل المجلد sites/ ثم انشاد في كل منهما المجلدات config/ وIMG/ وtmp/ وlocal/. ويجب علي هذه المجلدات الاربعة ان تكون مفتوحة للكتابة. يمكن في ما بعد اضافة مجلد squelettes/ الى جانب هذه المجلدات لتخزين الصفحات النموذجية.

 توزيع نطاق او نطاق فرعي (بعض الافكار):
اذا اردنا ان ينادي كل من العناوين /http://myuser.exemple.org و/http://exemple.net و/http://user.exemple.com موقع SPIP، يمكن في داخل مجلد sites/ انشاء مجلدات myuser/ وexemple.net/ وexemple.com/user/.

ملاحظة: يجب ان تدل كل عناوين URL الى اصل هرمية المجلدات حيث يوجد نظام SPIP اي في /home/myuser/public_html/. وهذا ما سيتكفل به اما ملف htaccess. او اعداد خادم اباشي المفصل لاحقاً.

اعادات توجيه حسنة الهندسة!

لكي يتعرف SPIP علي موقع مشترك، يجب تنفيذ سكريب spip.php (الذي يناديه index.php). وبفضل مقطع برمجي مضاف في config/mes_options.php/، سيقوم هذا الملف بالبحث بالتأكد من ان عنوان URL المطلوب يناسب موقع مشترك ام لا. من اجل ذلك، يجب يتم اعادة توجيه عنوان /http://exemple.org/first_site او /http://exemple.org/second_site نحو /http://exemple.org... لتنفيذ index.php.

وهذا هو الدور الذي يلعبه ملف htaccess. (او مباشرة في اعداد اباشي).

يجب نسخ ملف htaccess.txt الى اصل الهرمية واعادة تسميته htaccess. ثم تعديله:

للسماح بإعادة كتابة عناوين URL (لا شيء يتغير): RewriteEngine On

اذا كان نظام SPIP في مجلد فرعي، يجب تعديل rewritebase. في مثالنا يوجد النظام في اصل الهرمية، بالتالي: RewriteBase /.

اخيراً، في الاعدادات الشخصية، يجب اضافة المقطع التالي لكي تتم معالجة المجلدات first_site/ وsecond_site/ وthird_site/ من اصل الهرمية:

#Mutualisation
RewriteRule ^(first_site|second_site|third_site)$ /$1/ [R,L]
RewriteRule ^(first_site|second_site|third_site)/(.*) /$2 [QSA,L]

يعيد امر إعادة الكتابة RewriteRule الاول توجيه العناوين http://example.org/first_site نحو /http://example.org/first_site. ويعيد الامر الثاني توجيه كل ما يأتي بعد /first_site/ نحو اصل الموقع، مثلاً: تتم اعادة توجيه http://example.org/premier_site/article112 نحو http://example.org/article112. يذكر ان اعداة التوجيه هذه شفافة بالنسبة للمستخدم اذ ان محتوى عنوان URL لا يتغير ويبقى http://example.org/premier_site/article112 حتى (وخاصة) لـphp.

واذا كان SPIP داخل مجلد فرعي؟
في هذه الحال، تكون ملفات SPIP في /home/myuser/public_html/spip/ ويتم نداء SPIP بواسطة العنوان التالي /http://example.org/spip ونداء المواقع المشتركة الاول بواسطة /http://example.org/spip/first_site والثاني بواسطة /http://example.org/spip/second_site.

يجب اذن وضع التالي في ملف htaccess.:

RewriteEngine On
RewriteBase /spip/

#Mutualisation
RewriteRule ^(first_site|second_site|third_site)$ /spip/$1/ [R,L]
RewriteRule ^(first_site|second_site|third_site)/(.*) /spip/$2 [QSA,L]

ومن اجل اعادة توجيه كل المجلدات على انها مشتركة؟

يمكن بدلاً من أوامر إعادة الكتابة السابقة، استخدام رموز عامة يمكن استخدامها مهما كان اسم مجلد الموقع المشارك:
 في اصل الموقع

RewriteCond %{REQUEST_URI} !^/(config|squelettes-dist|ecrire|IMG|oo|plugins|sites|squelettes|tmp|local)/(.*)
RewriteRule ^[^/]+/(.*) /$1 [QSA,L]

 او في مجلد spip/:

RewriteCond %{REQUEST_URI} !^/spip/(config|squelettes-dist|ecrire|IMG|oo|plugins|sites|squelettes|tmp|local)/(.*)
RewriteRule ^[^/]+/(.*) /spip/$1 [QSA,L]

وللنطاقات والنطاقات الفرعية؟
من محاسن الصدف عدم فعل اي شيء هنا لأنها تدل عادة الى الاصل الذي يحتوي نظام SPIP...

توزيع حسب عنوان URL بفضل ملف mes_options.php

الملف config/mes_options.php/ الموجود في اصل النظام هو الذي سينفذ معظم المهمة: فيجب ان يبحث ما اذا كان عنوان URL ما بحاجة الى الاشتراك ام لا وتأصيل SPIP حسب ذلك.

وهنا تظهر عدة حالات تتعلق بالمجلدات والنطاقات والنطاقات الفرعية. يمكن لـPHP ان يستخدم متغيرين اثنين لاختبار عناوين URL التي طلبت الوظيفة:

<?php 
if ( preg_match(',/([a-zA-Z0-9_-]+)/?,',$_SERVER['REQUEST_URI'],$r)) {

    if (is_dir($e = _DIR_RACINE . 'sites/' . $r[1]. '/')) {

        $cookie_prefix = $table_prefix = $r[1]; 

        define('_SPIP_PATH',
            $e . ':' .
            _DIR_RACINE .':' .
            _DIR_RACINE .'squelettes-dist/:' .
	    _DIR_RACINE.'prive/:'.
            _DIR_RESTREINT);

        spip_initialisation(
            ($e . _NOM_PERMANENTS_INACCESSIBLES),
            ($e . _NOM_PERMANENTS_ACCESSIBLES),
            ($e . _NOM_TEMPORAIRES_INACCESSIBLES),
            ($e . _NOM_TEMPORAIRES_ACCESSIBLES)
            );

       $GLOBALS['dossier_squelettes'] = $e.'squelettes';

        if (is_readable($f = $e._NOM_PERMANENTS_INACCESSIBLES._NOM_CONFIG.'.php')) include($f);
    }
} 
?>

يقوم السطر preg_match باسترجاع اسم المجلد في هرمية عنوان URL، مثلاً «first_site» في /http://example.org/first_site ثم يحاول السكريبت مشاركة المجلد /sites/first_site/ اذا وجد.

اذا كان SPIP في مجلد فرعي spip/، يجب تعديل السطر الاول ليصبح:

if (preg_match(',/spip/([a-zA-Z0-9_-]+)/?,', $_SERVER['REQUEST_URI'], $r)) {

يجب اعلام SPIP ببادئة جدول قاعدة البيانات المستخدم، وهذا ما يفعله $cookie_prefix = $table_prefix = $r[1];. هذا السطر سينشئ جداول MySQL بادئات اسمائها مكونة من اسم المجلد الذي يحتوي الموقع: my_site_article بدلاً من spip_article مثلاً. ويسمح ذلك ببناء كل المواقع حول قاعدة بيانات واحدة. يمكن الاحتفاظ بالبادئة الافتراضية (spip) ولكن يجب انشاء عدة قواعد بيانات مختلفة، واحدة لكل موقع.
من اجل ذلك يجب تحديد التالي:

$cookie_prefix = $r[1]; 
$table_prefix='spip';

تتقبل دالة spip_initialisation تتقبل اربعة عوامل هي عناوين كل من المجلدات الضرورية لتشغيل الموقع المشترك.

يحدد $GLOBALS['dossier_squelettes'] = $e.'squelettes'; مكان مجلد الصفحات النموذجية العائدة للموقع المشترك.

في النهاية تقوم الاسطر الاخيرة بتحميل الملف sites/premier_site/config/mes_options.php اذا وجد.

معلومات:

اي تغيير في ملف config/mes_options.php العائد لنواة SPIP يؤثر على اعدادات كل المواقع التابعة له.

على سبيل المثال، اذا وضعنا في هذا الملف: $type_urls = ’propres’ ;
يعطي افتراضياً لكل المواقع هذا النوع من عناوين URL. ولكن يمكن لكل موقع تغييره في ملف sites/mon_site/config/mes_options.php/ الخاص به.

اعداد خادم اباشي لدعم النطاقات والنطاقات الفرعية

تبقى المشاركة من ناحية الخادم في ما يتعلق بالنطاقات والنطاقات الفرعية بسيطة جداً ولكنها تتطلب انشاء بعض اعادات توجيه عناوين URL في اعدادات خادم اباشي للاخذ في الاعتبار المواقع المتشاركة.

نعطي هنا مثال عن خادم اسمه «example.net» (نظام SPIP مشترك) يستخدم نطاقات فرعية (يتم نداء SPIP بواسطة / http://utilisateur.example.org/spip).

نواة SPIP موجودة في «/home/toto/public_html/spip/».

يجب انشاء المجلدات /sites/example.net/ و /sites/example.net/user/.

اما ملف الاعداد فيوجد في Apache 2/linux في المجلد etc/apache2/available_sites/default/ (يمكن ايضاً انشاء ملف جديد في المجلد available_sites وتفعيله).

# SERVER example.net
# SPIP by sub-domain...
<VirtualHost *>
        ServerName example.net
	ServerAlias *.example.net

        # اعادة توجيه نحو نواة SPIP
	DocumentRoot "/home/my_user/public_html"
	<Directory "/home/my_user/public_html/">
		AllowOverride All
		Order allow,deny
		Allow from all
	</Directory>

	# يجب اعادة توجيه العنوان http://utilisateur.example.net/spip/* فقط

	# (user.example.net/spip/* -> /home/my_user/public_html/*)
	RewriteCond %{SERVER_NAME} (www\.)?([^.]+)\.example\.net$
	RewriteRule ^/spip/(.*) /home/my_user/public_html/spip/$1 [QSA,L]

	# (user.example.net/* -> /home/my_user/public_html/sites/example.net/user/*)
	RewriteCond %{SERVER_NAME} (www\.)?([^.]+)\.example\.net$
	RewriteRule (.*) /home/my_user/public_html/sites/example.net/%1/$1 [QSA,L]

</VirtualHost>

الا انه من الضروري اختبار الاشتراكات الممكنة في ملف config/mes_options.php/:

<?php
# pour utilisateur.exemple.tld/spip/ 
if ( preg_match(',(.*)\.exemple\.tld/spip/?,',$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'],$r)) {

    if (is_dir($e = _DIR_RACINE . 'sites/exemple.tld/' . $r[1]. '/')) {

       $cookie_prefix = $table_prefix = $r[1]; 

       define('_SPIP_PATH',
            $e . ':' .
            _DIR_RACINE .':' .
            _DIR_RACINE .'squelettes-dist/:' .
            _DIR_RACINE.'prive/:'.
            _DIR_RESTREINT);

        spip_initialisation(
            ($e . _NOM_PERMANENTS_INACCESSIBLES),
            ($e . _NOM_PERMANENTS_ACCESSIBLES),
            ($e . _NOM_TEMPORAIRES_INACCESSIBLES),
            ($e . _NOM_TEMPORAIRES_ACCESSIBLES)
            );

       $GLOBALS['dossier_squelettes'] = $e.'squelettes';

        if (is_readable($f = $e._NOM_PERMANENTS_INACCESSIBLES._NOM_CONFIG.'.php')) include($f);
    }
} 
?>

ملاحظة حول النسخ الاحتياطي والاسترجاع

كل موقع يخزن نسخه الاحتياطية في المجلد sites/first_site/tmp/dump/ (او sites/premier_site/tmp/upload/login/ اذا كانت نسخة احتياطية لمدير محدود الامتيازات). ويتم استرجاع النسخة الاحتياطية من المجلد نفسه.

تحذير:

حالياً، وفي ما يتعلق بالمجلدة IMG/ العائد للمواقع المتشاركة، يقوم SPIP بتسجيل عنوان */sites/first_site/IMG بدلاً من */IMG في قاعدة البيانات كما في حال موقع SPIP منفرد.

لذلك لن ينجح الاسترجاع الا اذا تم في الموقع الذي انشأ النسخة الاحتياطية.

اما اذا اردنا استرجاع النسخة في مكان آخر، فيمكن تحرير ملف dump.xml واستبدال كل ظهور لعبارة /sites/premier_site/IMG (باستثناء اعلانات dir_img وdir_logo) بعبارة:
 /IMG (اذا كان SPIP بمفرده)
 /sites/my_new_site/IMG (اذا كان SPIP بالمشاركة)

في المقابل، لتحويل SPIP منفرد الى مجلد متشارك يجب استبدال كل ظهور لعبارة /IMG بعبارة /sites/my_site/IMG

(ستتم معالجة هذه المسألة في إصدار قادم من SPIP)

حواشي

[1اعادة توزيع المجلدات لتسهيل توزيع النواة وتصحيح مشاكل الدخول واسماء المواقع التي كانت تتضارب وعملية تأصيل موقع لاشتراكه اكثر سهولة.

[2للتوضيح، تم اختبار هذه العملية مع Apache 2.0.55 و PHP 5.1.2 في جهاز خدمة Ubuntu Dapper Drake وكذلك مع PHP 5.1.6 في جهاز خدمة Ubuntu Edgy Eft

مؤلف George نُشر في: تم التحديث: 26/10/12

الترجمات: عربي, català, English, Español, français, italiano, Türkçe