เว็บลิงค์ php รายได้ เลเยอร์เค้กและ com_weblinks Joomla ไฟล์อื่นๆ ที่ใช้ในส่วนประกอบ

เค้กชั้น

เราจะพูดถึงส่วนประกอบ com_weblinks และมาร์กอัป html ของหน้า Joomla เกี่ยวกับวิธีสร้างไดเรกทอรีของลิงก์บนเว็บไซต์ Joomla ได้อย่างง่ายดายและง่ายดาย

CMS นี้ถูกสร้างขึ้นเพื่อการทำงานเชิงโต้ตอบกับผู้ใช้ที่ลงทะเบียน โดยไม่ต้องเขียนโค้ดโดยตรง แม้ว่าแนวโน้มการพัฒนาของ Joomla จะนำไปสู่การละทิ้งส่วนประกอบ com_weblinks เนื่องจากไม่มีประโยชน์โดยสิ้นเชิงบนไซต์ และเพียงเพิ่มน้ำหนักพิเศษ (มากกว่า 100 kb - 90 ไฟล์) ให้กับระบบที่ "หนักหน่วง" อยู่แล้ว แต่สำหรับตอนนี้ส่วนประกอบนี้ยังคงมีอยู่ในการแจกจ่ายและโปรแกรมเมอร์บางคนใช้

หน้าเว็บไซต์ Joomla ที่ปรากฏบนหน้าจอนั้นเป็นเลเยอร์เค้ก ในการสร้างซึ่งมีหลายบล็อก (และหลายเทมเพลต) เกี่ยวข้องกันพร้อมๆ กัน นี่คือจุดที่ปรัชญาของ Joomla เข้ามามีบทบาท - การสร้างเว็บไซต์แบบบล็อกขนาดใหญ่ แต่ละบล็อกจะต้องมีเทมเพลตมาร์กอัป HTML (เค้าโครง) ของตัวเอง

บล็อกหลัก:

เทมเพลตหน้าหลัก (site_template/index.php) ซึ่งมีมาร์กอัป html จะกำหนดตำแหน่งสำหรับโมดูลและส่วนประกอบ และแสดงโมดูลและส่วนประกอบเหล่านี้
- เทมเพลตหน้า
- เทมเพลตโมดูล
- เทมเพลตส่วนประกอบ

แต่ละบล็อกขนาดใหญ่เหล่านี้พร้อมให้แก้ไข (เปลี่ยนแปลง) นั่นคือ คุณสามารถแก้ไขแยกกันได้ เช่น เทมเพลตของโมดูลหรือส่วนประกอบใดๆ และจะดูใหม่บนเพจ เช่นเดียวกับเทมเพลตเพจ

อาจเป็นเรื่องยากสำหรับโปรแกรมเมอร์มือใหม่ที่จะเข้าใจว่าบรรทัดแรกในส่วนเนื้อหาของเพจแสดงเป็นชื่อเพจ และได้รับการแก้ไขในหน้าแก้ไขของรายการเมนูที่ชี้ไปยังเพจนี้ บรรทัดที่สองได้มาจากเทมเพลตคอมโพเนนต์ com_content หรือ com_weblinks และสตริงในเทมเพลตมักจะเป็นตัวแปรสตริง และการกำหนดค่าเริ่มต้นและการแปลจะดำเนินการในไฟล์ภาษา เช่น language\ru-RU\ru-RU.mod_weblinks.ini และอื่นๆ ที่คล้ายกัน

บางครั้งผู้เริ่มต้นอาจสับสน: เทมเพลตใดที่สร้างบรรทัดนี้หรือบรรทัดนั้นซึ่งบนหน้าจอดูเหมือนเป็นความต่อเนื่องเชิงตรรกะของการเล่าเรื่องเดียวกัน ปรากฎว่ามีบรรทัดหนึ่งอยู่ในเทมเพลตหนึ่ง อีกบรรทัดอยู่ในเทมเพลตที่สอง และบรรทัดที่สามอยู่ในเทมเพลตที่สาม และตารางแบบแท็บด้านล่างนี้เป็นเอาต์พุตจากเทมเพลตโมดูล mod_tabform

บางครั้งเทมเพลตโมดูลเรียกว่าโครงร่าง แต่นี่เป็นคำถามของคำศัพท์ สาระสำคัญเหมือนกัน - มันคือ "เสื้อผ้า" สำหรับเนื้อหา การพูดการทำเครื่องหมายจะถูกต้องมากกว่า ดังนั้นมาร์กอัปของหน้าหนึ่งหน้าจอจึงอยู่ในไฟล์ไดเร็กทอรี Joomla ที่แตกต่างกัน

เมนู

โปรแกรมเมอร์ Joomla ใหม่จำนวนมากมักไม่เข้าใจว่ารายการเมนูสามารถมีได้หลายประเภท กล่าวอีกนัยหนึ่ง รายการเมนูสามารถอ้างถึงออบเจ็กต์ Joomla ประเภทต่างๆ สิ่งเหล่านี้อาจเป็นออบเจ็กต์ที่แตกต่างกัน เช่น: ส่วนประกอบ (การลงคะแนน การค้นหา ไดเร็กทอรีลิงก์ ฯลฯ)

การเลือกประเภทรายการเมนู:

ผู้ติดต่อ (com_contact)
รายการหมวดหมู่ผู้ติดต่อ (หมวดหมู่)
รายชื่อผู้ติดต่อตามหมวดหมู่ที่กำหนด (หมวดหมู่)
ติดต่อ
ผู้ติดต่อที่ชื่นชอบ (แนะนำ)

วัสดุ (com_content)
เอกสารสำคัญ (เอกสารสำคัญ)
วัสดุ (บทความ)
รายการหมวดหมู่ทั้งหมด (หมวดหมู่)
หมวดหมู่บล็อก
รายการหมวดหมู่วัสดุ (หมวดหมู่)
วัสดุที่โดดเด่น
สร้างวัสดุ

การค้นหาอัจฉริยะ (com_search)
ค้นหา

สวัสดีชาวโลก! (com_helloworld)
ข้อความ (สวัสดีชาวโลก)

ฟีดข่าว (com_newsfeeds)
รายการหมวดหมู่ฟีดข่าวทั้งหมด (หมวดหมู่)
รายการฟีดข่าวในหมวดหมู่ (หมวดหมู่)
ฟีดข่าว

ค้นหา (com_search)
แบบฟอร์มการค้นหาและรายการผลการค้นหา (ค้นหา)

ตัวจัดการผู้ใช้ (com_users)
แบบฟอร์มการอนุญาต (เข้าสู่ระบบ)
โปรไฟล์ผู้ใช้ (โปรไฟล์)
เปลี่ยนโปรไฟล์ผู้ใช้
แบบฟอร์มลงทะเบียน
การกู้คืนชื่อผู้ใช้ (เตือน)
การเปลี่ยนรหัสผ่าน (รีเซ็ต)

กระดาษห่อ (com_wrapper)
กระดาษห่อ

อย่างที่คุณเห็น เมนูทุกประเภทที่นี่เป็นส่วนประกอบ ตามชื่อ ประเภทรายการเมนูจะระบุชื่อเทมเพลตของประเภทส่วนประกอบจริงๆ และเทมเพลตส่วนประกอบจะอยู่ในไดเร็กทอรี view:

joomla\components\com_weblinks\views\categories
joomla\components\com_weblinks\views\category
joomla\components\com_weblinks\views\weblink
joomla\components\com_users\views\login

อย่างที่คุณเห็น ชื่อของประเภทลิงก์ในเมนูและชื่อของเทมเพลตในไดเร็กทอรี vews จะเหมือนกัน

นักพัฒนาสามารถสร้างเทมเพลต (เค้าโครง) ที่ไม่ได้มาตรฐานใหม่สำหรับส่วนประกอบ เค้าโครงใหม่เหล่านี้จะแสดงเป็นประเภทเมนูใหม่ในหน้าต่างการเลือกประเภทเมนู นี่เป็นหัวข้อแยกต่างหาก

เนื้อหาสาธิตการกระจาย Joomla

มาดูกันว่าลำดับชั้นของรายการเมนู "เกี่ยวกับ Joomla" ถูกสร้างขึ้นเพื่อแสดงส่วนประกอบ com_weblinks บนเนื้อหาสาธิตเริ่มต้น (Beez2 - ค่าเริ่มต้น) เทมเพลต Joomla อย่างไร

ไปที่แผงผู้ดูแลระบบเพื่อแก้ไขส่วนประกอบ com_weblinks: Components->Links เราเห็นว่าในเนื้อหาสาธิตที่มาพร้อมกับการแจกจ่าย มีการสร้างหมวดหมู่ห้าหมวดหมู่สำหรับส่วนประกอบ com_weblinks ซึ่งหมายความว่าลิงก์จะถูกแบ่งออกเป็นห้าหมวดหมู่ หมวดหมู่ที่สร้างขึ้นทั้งหมดจะถูกบันทึกไว้ในตารางฐานข้อมูล #_categories หมวดหมู่สำหรับส่วนประกอบอื่นๆ จะถูกจัดเก็บไว้ในตารางเดียวกันด้วย

ตัวอย่างข้อมูล-เว็บลิงค์
|-ปาร์คลิงค์
|-จูมล่า! ลิงค์เฉพาะ
|-|-แหล่งข้อมูลอื่นๆ
ไม่มีหมวดหมู่

ในเมนูเกี่ยวกับ Joomla (ในตัวแก้ไขเมนู) ลำดับชั้นของรายการเมนูจะถูกสร้างขึ้นตามลำดับ:

ลำดับชั้นของรายการเมนู:

การใช้จูมล่า! (ประเภท: วัสดุ)
|-การใช้ส่วนขยาย (ประเภท: รายการหมวดหมู่ทั้งหมด) :: รายการหมวดหมู่ในสื่อ
|-|-ส่วนประกอบ (ประเภท: หมวดหมู่บล็อก) :: หมวดหมู่ในวัสดุ
|-|-|-ส่วนประกอบของเว็บลิงก์ (ประเภท: วัสดุ)
|-|-|-|-ส่งเว็บลิงก์ (ประเภท: สร้างลิงก์) :: ในส่วนประกอบลิงก์
|-|-|-|-Weblinks Single Category (ประเภท: รายการลิงก์ในหมวดหมู่) :: ในส่วนประกอบลิงก์
|-|-|-|-หมวดหมู่เว็บลิงก์ (ประเภท: รายการหมวดหมู่ลิงก์) :: ในส่วนประกอบลิงก์

เราจะเห็นว่ารายการเมนูบางรายการมีประเภทดังต่อไปนี้ รายการหมวดหมู่ รายการลิงก์ในหมวดหมู่ และสร้างลิงก์
"รายการหมวดหมู่ลิงก์" ระบุหมวดหมู่บนสุดที่จะแสดงลำดับชั้น
"รายการลิงก์ในหมวดหมู่" ระบุหมวดหมู่ที่ลิงก์จะแสดง
ในรายการ "สร้างลิงก์" แบบฟอร์มจะปรากฏขึ้นซึ่งผู้ใช้ที่ลงทะเบียนจะต้องกรอก
อย่างไรก็ตามนี่คือลักษณะของลิงก์ไปยังแบบฟอร์มนี้ในตัวแก้ไข (ลักษณะที่ปรากฏจะเปลี่ยนไปในแถบที่อยู่):

index.php?option=com_weblinks&view=form&layout=edit

รายการเมนูบางรายการสามารถแสดงให้ผู้ใช้ที่ลงทะเบียนเท่านั้น! ตัวอย่างเช่น รายการเมนูประเภท "สร้างลิงก์" จะมองเห็นได้เฉพาะผู้ใช้ที่ลงทะเบียนเท่านั้น คุณลักษณะนี้ถูกสร้างขึ้นโดยเฉพาะเพื่อให้ผู้ใช้ที่ลงทะเบียนสามารถสร้างลิงก์ที่จะโพสต์บนเพจได้

ดังนั้น คอมโพเนนต์ com_weblinks จึงเป็นวิธีที่ดีในการเติมหน้าเว็บที่มีลิงก์ที่น่าสนใจแบบโต้ตอบ นอกจากนี้ ลิงก์ทั้งหมดที่จะวางบนหน้าดังกล่าวมีการเปลี่ยนเส้นทาง กล่าวคือ ลิงก์เหล่านี้จะไม่ถูกจัดทำดัชนีเป็นภายนอก คุณอาจเคยเห็นลิงก์ดังกล่าวในฟอรัม เมื่อคุณวางเมาส์เหนือลิงก์ดังกล่าว คุณจะเห็นที่อยู่ของเว็บไซต์ของคุณ และหลังจากคลิกแล้วเท่านั้น คุณจะถูกนำไปยังที่อยู่ที่คุณระบุ

ความสามารถสำหรับผู้ใช้ในการเพิ่มลิงก์ไปยังไซต์ภายนอกเป็นข้อได้เปรียบหลักและความหมายของส่วนประกอบ com_weblinks เช่นเดียวกับความสามารถสำหรับผู้ใช้ในการเพิ่มเนื้อหาใหม่ - บทความ รูปภาพ ไฟล์วิดีโอ ฯลฯ

การอนุญาตให้ผู้ใช้ที่ลงทะเบียนมีสิทธิ์ในการกรอกเนื้อหาบนเว็บไซต์โดยไม่ต้องเขียนโค้ดโดยตรงถือเป็นปรัชญาพื้นฐานของ CMS Joomla

ไม่มีหมวดหมู่
ตัวอย่างข้อมูล-บทความ
|- จูมล่า!
|-|- ส่วนขยาย
|-|-|- ส่วนประกอบ
|-|-|- โมดูล
|-|-|-|- โมดูลเนื้อหา
|-|-|-|- โมดูลผู้ใช้
|-|-|-|- โมดูลการแสดงผล
|-|-|-|- โมดูลยูทิลิตี้
|-|-|-|- โมดูลการนำทาง
|-|-|- เทมเพลต
|-|-|-|- อะตอม
|-|-|-|- บีซ 20
|-|-|-|- บีซ 5
|-|-|- ภาษา
|-|-|- ปลั๊กอิน
|- เว็บไซต์อุทยาน
|-|- บล็อกของปาร์ค
|-|- แกลเลอรี่ภาพ
|-|-|- สัตว์
|-|-|- ทิวทัศน์
|- เว็บไซต์ร้านขายผลไม้
|-|-ผู้ปลูก
|-|- สูตรอาหาร

ดูเหมือนจะไม่มีหมวดหมู่เนื้อหามากเกินไป!
คุณยังสามารถดูลำดับชั้นของหมวดหมู่ในวัสดุโดยใช้แบบสอบถามไปยังตารางหมวดหมู่ในฐานข้อมูล:

SELECT * จาก `#_categories` โดยที่ `extension` = "com_content"

มีข้อเสนอแนะในไฟล์ /includes/joomla.php ในฟังก์ชัน cleanText เพื่อแทนที่บรรทัด

$text = strip_tags($ข้อความ); " ) ;

$text = strip_tags ( $text , "

แฮ็คนี้มีไว้สำหรับรูปภาพที่แทรกเป็นรูปภาพปกติเท่านั้น สำหรับรูปภาพที่แทรกโดยแมมบอต (mosimage) การแฮ็กนี้จะไม่ทำงาน

วิธีทำให้ลิงก์โดยตรงปรากฏในคอมโพเนนต์ com_weblinks

ใน weblinks.html.php คุณต้องแทนที่บรรทัด:

ประการแรก ประเด็นสำคัญของปัญหาคือ Joomla แสดงรูปภาพและไฟล์ CSS ทั้งหมด (เส้นทางในเทมเพลต) โดยสัมพันธ์กับตัวแปร $mosConfig_live_site ซึ่งเป็นที่อยู่พื้นฐานของไซต์ที่ป้อนระหว่างการติดตั้ง และหากมีคนพยายามเข้าถึงด้วยที่อยู่อื่น ตรรกะของการดำเนินการจะไม่เปลี่ยนแปลง - ที่อยู่ฐานจะถูกดึงมาจากไฟล์กำหนดค่า ตัวอย่างเช่น หากการกำหนดค่าระบุว่า Joomla ตั้งอยู่บน localhost การเข้าถึงจากเครือข่ายท้องถิ่น แม้แต่ไปยัง Apache ที่กำหนดค่าอย่างถูกต้องซึ่งรับฟังที่อยู่ 192.168.0.1 จะไม่เปลี่ยนแปลงสิ่งใดในนั้น - src ของรูปภาพจะยังคงเริ่มต้น ด้วย "localhost" ซึ่งสำหรับเครื่องอื่น ๆ จะมี localhost ของตัวเองอยู่แล้ว จุดเน้นของการแก้ปัญหาสำหรับกรณีดังกล่าวคือการแทนที่ตัวแปร $mosConfig_live_site สำหรับโฮสต์ที่ร้องขอเพื่อให้ฟังก์ชันทั้งหมดสามารถออกลิงก์ที่ถูกต้องและนำผู้ใช้ไปสู่ ไซต์เสมือนอย่างใดอย่างหนึ่ง (ให้เส้นทางพื้นฐานที่ถูกต้องไปยังรูปภาพและเส้นทางพื้นฐานไปยังที่อยู่) มีแมมบอตไซต์สดอัตโนมัติที่สามารถทำให้สิ่งนี้เป็นอัตโนมัติได้ หากไม่เหมาะกับคุณในทางใดทางหนึ่ง ก็สามารถทำซ้ำได้ ; สำหรับสิ่งนี้ ใน configuration.php แทนที่คำจำกัดความ $mosConfig_live_site คุณต้องเขียนโค้ดของคุณ เช่น:

ถ้า ($_SERVER [ "HTTP_HOST" ] =="host1.ru" ) $mosConfig_live_site = "host1.ru" ;

อย่างอื่น $mosConfig_live_site = "host2.ru" ;

จำเป็นต้องให้ความสนใจว่าหากคุณใช้แคชคุณจะต้องมีไดเร็กทอรีแคชที่แตกต่างกันสองแห่งสำหรับสองโฮสต์เนื่องจากลิงก์ไปยังโฮสต์ที่ต่างกันอาจตัดกันในแคชจากนั้นผู้ใช้จากเครือข่ายที่ไม่ถูกต้องจะไม่ได้รับที่ใดก็ได้เลย . ตัวแปร $mosConfig_cachepath รับผิดชอบแคช

วิธีทำให้สององค์ประกอบปรากฏพร้อมกันในหน้าเดียว

ฉันจะบอกคุณทันที - ไม่ใช่ทุกอย่างจะง่ายนัก มันไม่ใช่โมดูลเลย ดังนั้นประการแรกจึงควรมองหาทางเลือกอื่นเช่น แน่นอนว่าส่วนประกอบยอดนิยมมาพร้อมกับโมดูลที่สามารถจำลองฟังก์ชันการทำงานได้ ถ้าไม่มีอะไรแบบนั้นก็เป็นทางเลือก สามารถสร้างเป็นโมดูลหรือตามทฤษฎีแล้วสามารถแทรกลงในเทมเพลตได้ แนวคิดก็คือ - การเรียกส่วนประกอบผ่าน index2.php (อะไรและทำไม - อ่านข้อเท็จจริงทั้งหมด) เหล่านั้น. คุณสามารถสร้าง iframe ด้วย src="index2.php?option=com_component&no_html=1" ที่จุดแทรกที่ต้องการสำหรับองค์ประกอบที่สอง และมันจะแสดงอยู่ที่นั่น อีกประการหนึ่งคือไม่น่าเป็นไปได้ที่จะรับประกันการใช้งานได้อย่างเต็มที่ แต่อย่างไรก็ตาม นี่เป็นทางออก

แต่ถ้าคอมโพเนนต์ถูกดำเนินการในลักษณะนี้ คุณจะต้องเข้าใจว่าคอมโพเนนต์ไม่ทราบเกี่ยวกับการปรับแต่งของคุณ และจะทำงานตาม $option และ $task

วิธีเพิ่มความยาวของชื่อเรื่องในบทความ

คุณต้องรันสองคำสั่งต่อไปนี้ใน phpMyAdmin (มีหน้าพิเศษสำหรับดำเนินการสืบค้น SQL) เพียงแทนที่ ###_ ด้วยคำนำหน้าตารางจริงของคุณ จำนวนสูงสุดที่เป็นไปได้คือ 255 ในตัวอย่าง จะใช้ 200

แก้ไขตาราง `###_content` เปลี่ยน `title_alias` `title_alias` VARCHAR (200) ไม่เป็นโมฆะ; แก้ไขตาราง `###_content` เปลี่ยน `title` `title` VARCHAR(200) ไม่เป็นโมฆะ;

วิธีรวมข้อความข่าวฉบับสมบูรณ์ในฟีด RSS ของคุณ ไม่ใช่แค่พาดหัวข่าว

ในการดำเนินการนี้ คุณต้องแทนที่ในไฟล์ /components/com_rss/rss.php

$item_description = $row ->ข้อความนำ ;

$item_description = $row ->ข้อความแบบเต็ม ; ฉันสามารถสร้างเว็บไซต์ Joomla สองแห่งโดยใช้ฐานข้อมูลเดียวกันหรือใช้ไฟล์เดียวกันได้อย่างไร

สำหรับการใช้ฐานข้อมูลเดียว คุณต้องเขียนฐานข้อมูลหนึ่งฐานข้อมูลใน configuration.php สำหรับสองเอ็นจิ้น แต่คุณต้องเข้าใจว่าคุณกำลังทำอะไรอยู่ เพราะการดูแลเซสชันสำหรับผู้ใช้ในกรณีนี้จะเป็นปัญหาอย่างมากเนื่องจากโดเมนต่างกัน เหล่านั้น. รายการเข้าสู่ระบบในตาราง #__sessions จะ (อาจ) ทับซ้อนกัน

หากคุณต้องการใช้ไฟล์เดียวกันโดยไม่ต้องคัดลอกการแจกจ่ายจำนวนมาก โดยหลักการแล้ว คุณสามารถใช้คำสั่ง "ln -s" ใน Linux เพื่อสร้างลิงก์สัญลักษณ์ไปยังไฟล์ที่มีอยู่ และไม่คัดลอกลิงก์เหล่านั้นสำหรับไซต์ใหม่
  • วิธีสร้างเพจเสมือนที่สามารถเข้าถึงได้ตามที่อยู่เฉพาะในการออกแบบ Joomla ทั่วไป (http:// /site.ru/super_page)
  • วิธีแรกคือการใช้ส่วนประกอบ SEF บางประเภท ซึ่งคุณระบุเส้นทางเสมือนที่ต้องการสำหรับเพจแบบคงที่ มีข้อเสียอยู่ตรงนี้ - ส่วนประกอบนี้จะเริ่มสร้างลิงก์อื่น ๆ ทั้งหมดใหม่ (และโดยทั่วไปส่วนประกอบเหล่านี้ใช้พลังงานมากและต้องใช้ทรัพยากรจำนวนมากในการทำงาน)
    • สร้างนามแฝงสำหรับเพจดังกล่าวโดยใช้ mod_rewrite และ .htaccess ในการทำเช่นนี้คุณต้องมี:
    • สร้างเพจแบบคงที่พร้อมข้อความที่คุณต้องการ ค้นหา ID และที่อยู่ (ไม่จำเป็นต้องสร้างเพจดังกล่าว อาจมีอยู่แล้วและโดยทั่วไปเป็นเพียงส่วนประกอบใด ๆ ไม่จำเป็นต้อง com_content)
    • ตั้งนามแฝงให้เป็น "super_puper"
เปิด .htaccess และก่อนบรรทัด "RewriteCond %(REQUEST_FILENAME) !-f" ให้เขียน:
    • และตอนนี้ โดยมีเงื่อนไขว่า Joomla จะอยู่ที่ site.ru เมื่อคุณเปิดลิงก์ http:// /site.ru/super_puper หน้าคงที่ที่จำเป็นพร้อมข้อมูลของคุณจะเปิดขึ้น ลิงก์ "index.php?option=com_content&task=view&id=12" เองสามารถเป็นอะไรก็ได้ที่คุณต้องการ สิ่งสำคัญคือลิงก์นั้นไม่สมบูรณ์ (เช่น ด้วย http:/ /...) แต่สัมพันธ์กัน (ต้องขึ้นต้นด้วยดัชนี .php?...)
วิธีปิดการใช้งานแคชสำหรับบทความใดบทความหนึ่ง

นี่อาจจำเป็นหากคุณใช้แมมบอต rd_addphp เพื่อแทรกสคริปต์ใดๆ ที่ควรสร้างตัวเลขสุ่มหรือข้อความสุ่มทุกครั้ง โดยไม่คำนึงถึงระบบแคชของ Joomla หากต้องการปิดใช้งานการแคชของบางรายการ คุณต้องค้นหา ID ของมัน (ในแผงผู้ดูแลระบบ เมื่อทำการแก้ไข ให้ดูที่แถบที่อยู่ มันจะพูดประมาณว่า "...&id=123...") ดังนั้น 123 จะเป็นรหัสบทความของเรา จำเป็นต้องแทนที่ในไฟล์ /components/com_content/content.php ประมาณบรรทัดที่ 1600

$แคช ->โทร ( "HTML_content::show" , $row , $params , $access , $page ) ;

ถ้า ($row ->id !="123" ) $cache ->call ( "HTML_content::show" , $row , $params , $access , $page ) ;

อื่น HTML_content::show ($แถว, $params, $access, $page);

โดยที่ 123 คือรหัสบทความที่คุณต้องการ

ฉันติดตั้งส่วนประกอบจำนวนมาก แต่รายการส่วนประกอบในเมนูผู้ดูแลระบบแสดงจำนวนส่วนประกอบที่ลดลง และจากนั้นจะมีข้อความว่า "ส่วนประกอบเพิ่มเติม..." วิธีแสดงส่วนประกอบทั้งหมด

คุณต้องมีบรรทัดในไฟล์ /administrator/modules/mod_fullmenu.php

$topLevelLimit = 19 ;

แทนที่ด้วย

  • $topLevelLimit = 199 ; วิธีติดตั้งสำเนาของส่วนประกอบ
  • ต้องบอกว่างานนี้ยากมาก หากคุณไม่เข้าใจวิธีการทำงานของส่วนประกอบ คุณไม่ควรลองด้วยซ้ำ สำหรับผู้ที่ยังต้องการทราบประเด็นหลัก:
  • ในไฟล์ XML ให้เปลี่ยนชื่อส่วนประกอบในแท็กชื่อ

ถัดไป คุณต้องเปลี่ยนชื่อตารางที่ใช้ (ประการแรกในไฟล์ XML และประการที่สองในไฟล์ส่วนประกอบทั้งหมด ไม่ว่าจะใช้ออบเจ็กต์ฐานข้อมูล $database และวิธีการ setQuery ก็ตาม)

เปลี่ยนชื่อเส้นทางทั้งหมดในส่วนประกอบด้วย สามารถใช้พาธในการอ้างอิงถึงตัวมันเองหรือในชื่อของไฟล์ที่รวมไว้ บ่อยครั้งสิ่งนี้เกิดขึ้นจากการค้นหาชื่อสตริงย่อย com_component และแทนที่ด้วยชื่อใหม่
  • ตัวเลือกที่ 1 - แฮ็กฟังก์ชัน mosLoadModules ในเทมเพลตในตำแหน่งที่จำเป็นในการแสดงหนึ่งในโมดูล N เราเขียน (ให้ความสนใจกับอาร์กิวเมนต์ที่สาม):
mosLoadModules("ตำแหน่ง", display_setup,true);

และเราแก้ไขฟังก์ชันข้างต้นเล็กน้อย:

ฟังก์ชั่น mosLoadModules( $position ="left" , $style =0 , $show_random = false ) ( ... $allModules =& initModules() ; if (isset ( $GLOBALS [ "_MOS_MODULES" ] [ $position ] ) ) ( $modules = $GLOBALS [ "_MOS_MODULES" ] [ $position ] ) else ( $modules = array () ; ) // เพิ่มที่นี่ถ้า ($show_random && sizeof ($modules ) >0 ) ( $tmp = $modules [ rand (0 ,ขนาดของ ($modules ) -1 ) ] ; $modules = array ($tmp ) ; // สิ้นสุดคำสั่ง if ( count ( $modules )< 1 ) { $style = 0 ; }

เราได้เพิ่มอาร์กิวเมนต์ที่สามลงไป (ซึ่งใช้ในเทมเพลตโดยที่เราเขียนว่าเป็นจริง) และแก้ไขโค้ด

  • ตัวเลือกที่สองนั้นไม่ยุ่งยากกว่า เราแก้ไขเทมเพลตเท่านั้น แต่ต้องใช้แรงงานมากขึ้น - เราจำเป็นต้องสร้างหลายตำแหน่ง ขั้นแรก เราสร้างตำแหน่งโมดูลใหม่หลายตำแหน่ง เช่น new1 ... new10 บันทึก. ในตำแหน่งที่ถูกต้องในเทมเพลต ก่อนที่จะเรียกใช้ฟังก์ชัน mosLoadModules ให้เพิ่มโค้ดที่จำเป็น:
$rand_num = rand (1 ,10 ) ;//จาก 1 ถึง 10 - เช่นเดียวกับในชื่อตำแหน่ง mosLoadModules ( "new" .$rand_num , display_settings) ; ฉันเชื่อว่าการเปลี่ยนชื่อโฟลเดอร์ /adminisrator/ ฉันจะทำให้ไซต์ของฉันปลอดภัยยิ่งขึ้น

ตัวเลือกนี้ไม่ได้จัดเตรียมไว้เป็นมาตรฐาน แต่ในความเป็นจริง เป็นไปได้โดยการจัดระเบียบการค้นหาในไฟล์ Joomla เพื่อแทนที่คำดังกล่าวด้วยคำของคุณ - ความลับ บางครั้งข้อผิดพลาดอาจปรากฏขึ้นในภายหลังเกี่ยวกับการไม่สามารถเข้าถึงไฟล์ แต่เมื่อรู้ไฟล์และหมายเลขบรรทัดก็สามารถแก้ไขได้ ดังนั้นโดยหลักการแล้วปัญหาคือแก้ไขได้

ในเดือนนี้ ผู้ขุดแมลงไม่ต้องการทำลายเราด้วยการหาประโยชน์ใหม่ๆ ที่โด่งดังในแอปพลิเคชันยอดนิยม แน่นอนว่ามีการเผยแพร่คำแนะนำจำนวนมากในผลิตภัณฑ์ของบริษัทที่มีชื่อเสียง แต่มีเพียงไม่กี่รายการเท่านั้นที่มีรหัส PoC ที่อ่านได้ ในการตรวจสอบของเรา ฉันพยายามรวบรวมช่องโหว่ที่สำคัญและครบถ้วนที่สุดที่อธิบายไว้เมื่อเร็ว ๆ นี้ ดังนั้นโปรดนั่งและสนุกกับการอ่าน

ช่องโหว่ PHP เมื่อประมวลผลคำขอ HTTP Head Brief

เมื่อวันที่ 3 มีนาคม Adam Ivanyuk คนหนึ่งค้นพบคุณลักษณะที่น่าสนใจในล่าม PHP ซึ่งประมวลผลคำขอ HEAD ได้ไม่ถูกต้องนัก นักวิจัยเรียกช่องโหว่นี้ว่า “เคล็ดลับวิธี HTTP HEAD ในสคริปต์ php”

ผู้เขียนโค้ดจำนวนมากออกแบบสคริปต์ PHP โดยหวังว่าคำสั่งทั้งหมดที่เขียนในนั้นจะดำเนินการได้สำเร็จโดยไม่ขาดตรงกลาง (โดยเฉพาะในสคริปต์สั้น) นี่คือสิ่งที่เกิดขึ้นหากผู้ใช้ร้องขอสคริปต์โดยใช้วิธี GET, POST, PUT

แต่คุณควรรู้ว่ามีวิธี HTTP อื่นๆ เช่น HEAD เมื่อประมวลผลวิธีนี้ใน PHP อาจมีช่องโหว่ด้านความปลอดภัยเกิดขึ้น

ลองดูที่แหล่งล่ามแหล่งใดแหล่งหนึ่ง: ./main/SAPI.c บรรทัด 315:

ถ้า (SG (request_info).request_method &&
!strcmp(SG(request_info).request_method, "HEAD"))
{
SG(request_info).headers_only = 1;
...

เมื่อมีข้อมูลมาถึง ฟังก์ชัน php_ub_body_write จะถูกดำเนินการ ถัดไป ดูที่ main/output.c บรรทัด 699:

ถ้า (SG(request_info).headers_only) (
ถ้า(SG(headers_sent))
{
กลับ 0;
}
php_header(TSRMLS_C);
zend_bailout();
}

ที่นี่คุณจะเห็นว่าในครั้งแรกที่พิมพ์ลงบนหน้าจอ และเมื่อใช้วิธี HEAD ฟังก์ชัน zend_bailout จะแบ่งสคริปต์

หาประโยชน์

ตอนนี้เรามาเข้าถึงสคริปต์นี้โดยใช้วิธี HEAD:

ตามที่คุณคาดหวัง Guest Book ของเราจะหยุดดำเนินการที่บรรทัด “echo $data;” ดังนั้นไฟล์ book.txt จะถูกรีเซ็ตเป็นศูนย์
ตัวอย่างนี้ค่อนข้างจะเป็นอันตราย ในตัวอย่างที่สอง เราสามารถข้ามการอนุญาตในแผงการดูแลระบบแบบพื้นฐานได้:

ในสคริปต์นี้ เมื่อเข้าสู่ระบบโดยใช้วิธีปกติ ตัวแปรผู้ดูแลระบบจะถูกตั้งค่าในเซสชัน จากนั้น หากผู้ใช้ป้อนรหัสผ่านไม่ถูกต้อง ตัวแปรนี้จะถูกรีเซ็ตและผู้ใช้จะไม่กลายเป็นผู้ดูแลระบบ

หากเราเข้าถึงแผงผู้ดูแลระบบผ่านทาง HEAD การดำเนินการจะถูกขัดจังหวะด้วยโค้ดที่มีคำว่า "echo" ดังนั้นตัวแปรผู้ดูแลระบบจะไม่ถูกรีเซ็ต และเราสามารถเดินไปรอบๆ ส่วนที่ปิดของแอปพลิเคชันได้อย่างปลอดภัย สิ่งที่ต้องจำไว้คือ เว็บเซิร์ฟเวอร์ส่วนใหญ่มีค่าบัฟเฟอร์เอาต์พุตตั้งไว้ที่ 4096 ไบต์ ดังนั้นในตัวอย่างการทำงาน เราอาจต้องใช้สตริง "A long string contains about 4090 character"

หาประโยชน์
  • PHP

    ในที่นี้ $check array มีข้อมูล POST ของเรา และตัวแปร $locked นั้นเป็นสตริงแบบซีเรียลไลซ์ที่สร้างความสับสนโดยใช้ฟังก์ชัน str_rot13() ซึ่งอยู่ภายใต้การควบคุมของเราโดยสมบูรณ์

    ณ จุดนี้ มันคุ้มค่าที่จะพูดนอกเรื่องเล็กน้อยสำหรับผู้ที่ยังไม่ได้อ่านบทความที่เกี่ยวข้องใน ][ และพูดคุยสั้น ๆ เกี่ยวกับข้อผิดพลาดที่ปรากฏในวิธีการมหัศจรรย์ของ PHP ดังนั้นใน PHP เวอร์ชัน 5 แนวคิดพื้นฐานของการเขียนโปรแกรม OOP จึงปรากฏขึ้น: ตัวสร้างและตัวทำลาย ตัวสร้างถูกนำมาใช้โดยใช้วิธี "__construct" และตัวทำลายถูกนำมาใช้โดยใช้วิธี "__destruct" เมื่อทำงานเสร็จแล้วและเมื่อถูกเรียกผ่านฟังก์ชัน unserialize() แต่ละอ็อบเจ็กต์จะดำเนินการเมธอด __ destruct ของตัวเอง ถ้ามันเขียนด้วยโค้ด

    ตอนนี้กลับไปที่เฟรมเวิร์กของเราแล้วดูตัวทำลายคลาส App จากไฟล์ ./libs/configure.php:

    ฟังก์ชั่น __ ทำลาย ()
    {
    ถ้า ($ นี่ -> __ แคช)
    {
    $core = App::core("เค้ก");
    ไม่ได้ตั้งค่า($this->__paths);
    แคช::write("dir_map", array_fi lter($this->__paths)
    "เค้ก_คอร์");
    แคช::write("fi le_map", array_fi lter($this->__map)
    "เค้ก_คอร์");
    แคช::write("object_map", $this->__objects,
    "เค้ก_คอร์");
    }
    }

    จากโค้ดด้านบนจะเห็นว่าวิธีนี้สามารถถูกโจมตีได้โดยการเขียนค่าที่กำหนดเองลงใน Cache object คีย์ที่น่าสนใจที่สุดในการถอดรหัสคือ 'file_map' โดยจะจัดการการเชื่อมต่อระหว่างคลาสและไฟล์ PHP ที่เกี่ยวข้อง และยังใช้เพื่อโหลดคลาสเพิ่มเติมระหว่างการเรียกใช้สคริปต์อีกด้วย

    โค้ดจริงสำหรับการโหลดคลาสนั้นซับซ้อนกว่าเล็กน้อย แต่ทั้งหมดนั้นมาจากโค้ดต่อไปนี้จากวิธี __load ภายในคลาส App:

    บิงโก! ด้วยการแทนที่ตัวแปร $file เราก็สามารถรวมโค้ด PHP ของเราเองได้! ยิ่งไปกว่านั้น นี่จะเป็นข้อบกพร่องของการรวมไฟล์ระยะไกลจริง ๆ ดังนั้นเราจึงไม่ต้องการเทคนิคเพิ่มเติมใด ๆ ในการอัปโหลดไฟล์ในเครื่องไปยังเซิร์ฟเวอร์ อย่างไรก็ตาม ผู้เขียนช่องโหว่ที่พบเสนอตัวเลือก LFI สำหรับการใช้ประโยชน์จากช่องโหว่นี้ เนื่องจาก CakePHP ใช้แคชในเครื่องตามไฟล์ ซึ่งอยู่ในรูปแบบซีเรียลไลซ์ในไดเร็กทอรีที่ผู้โจมตีรู้จัก

    หาประโยชน์

    เนื่องจากเป็น PoC ขนาดเล็กสำหรับสร้างสตริงซีเรียลไลซ์ที่เป็นพิษ felix จึงเสนอโค้ดต่อไปนี้:

    แน่นอนว่าคุณต้องรวมคลาสที่จำเป็นจาก CakePHP ก่อน นอกจากนี้ยังมีการหาประโยชน์จาก Python ที่ทำงานได้อย่างสมบูรณ์ ซึ่งคุณสามารถพบได้ที่ malloc.im/burnedcake.py

    ช่องโหว่นี้ควรใช้ได้กับทุกแอปพลิเคชันที่สร้างบน CakePHP โดยใช้แบบฟอร์ม POST พร้อมโทเค็นความปลอดภัย และไม่มีการเปลี่ยนแปลงตำแหน่งมาตรฐานของไฟล์แคช ตามค่าเริ่มต้น การใช้ประโยชน์จะแสดงการกำหนดค่าฐานข้อมูล คุณสามารถเพิ่มคุณสมบัติที่มีประโยชน์อื่น ๆ ได้อย่างง่ายดายโดยการเปลี่ยนเพย์โหลด PHP ในตัว

    เป้าหมาย
    • CakePHP getState("fi lter_order_dir");
      $fi lter_order = JFilterInput::clean($fi lter_order, "cmd");
      $fi lter_order_dir =
      JFilterInput::clean($fi lter_order_dir, "คำ");
      // เราจำเป็นต้องได้รับรายชื่อทั้งหมด
      // เว็บลิงค์ในหมวดหมู่ที่กำหนด
      $query = "เลือก *" .
      "จาก #__เว็บลิงก์"
      "อยู่ที่ไหน catid = ". (int) $นี่->_id.
      "และเผยแพร่ = 1"
      "และเก็บถาวร = 0"
      "สั่งซื้อโดย" $fi lter_order ""
      $fi lter_order_dir ”, กำลังสั่งซื้อ”;
      ส่งคืน $ แบบสอบถาม;
      }

      ที่นี่คุณจะเห็นว่าตัวแปร $filter_order และ $filter_order_dir ไม่ได้ถูกตรวจสอบการปฏิบัติตามคำสั่ง SQL อย่างเข้มงวด การตรวจสอบจะดำเนินการโดยใช้เมธอด clean มาตรฐานจากคลาส JFilterInput เท่านั้น: