image-carousel.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. <?php
  2. namespace Elementor;
  3. if ( ! defined( 'ABSPATH' ) ) {
  4. exit; // Exit if accessed directly.
  5. }
  6. /**
  7. * Elementor image carousel widget.
  8. *
  9. * Elementor widget that displays a set of images in a rotating carousel or
  10. * slider.
  11. *
  12. * @since 1.0.0
  13. */
  14. class Widget_Image_Carousel extends Widget_Base {
  15. /**
  16. * Get widget name.
  17. *
  18. * Retrieve image carousel widget name.
  19. *
  20. * @since 1.0.0
  21. * @access public
  22. *
  23. * @return string Widget name.
  24. */
  25. public function get_name() {
  26. return 'image-carousel';
  27. }
  28. /**
  29. * Get widget title.
  30. *
  31. * Retrieve image carousel widget title.
  32. *
  33. * @since 1.0.0
  34. * @access public
  35. *
  36. * @return string Widget title.
  37. */
  38. public function get_title() {
  39. return __( 'Image Carousel', 'elementor' );
  40. }
  41. /**
  42. * Get widget icon.
  43. *
  44. * Retrieve image carousel widget icon.
  45. *
  46. * @since 1.0.0
  47. * @access public
  48. *
  49. * @return string Widget icon.
  50. */
  51. public function get_icon() {
  52. return 'eicon-slider-push';
  53. }
  54. /**
  55. * Get widget keywords.
  56. *
  57. * Retrieve the list of keywords the widget belongs to.
  58. *
  59. * @since 2.1.0
  60. * @access public
  61. *
  62. * @return array Widget keywords.
  63. */
  64. public function get_keywords() {
  65. return [ 'image', 'photo', 'visual', 'carousel', 'slider' ];
  66. }
  67. /**
  68. * Retrieve the list of scripts the image carousel widget depended on.
  69. *
  70. * Used to set scripts dependencies required to run the widget.
  71. *
  72. * @since 1.3.0
  73. * @access public
  74. *
  75. * @return array Widget scripts dependencies.
  76. */
  77. public function get_script_depends() {
  78. return [ 'jquery-slick' ];
  79. }
  80. /**
  81. * Register image carousel widget controls.
  82. *
  83. * Adds different input fields to allow the user to change and customize the widget settings.
  84. *
  85. * @since 1.0.0
  86. * @access protected
  87. */
  88. protected function _register_controls() {
  89. $this->start_controls_section(
  90. 'section_image_carousel',
  91. [
  92. 'label' => __( 'Image Carousel', 'elementor' ),
  93. ]
  94. );
  95. $this->add_control(
  96. 'carousel',
  97. [
  98. 'label' => __( 'Add Images', 'elementor' ),
  99. 'type' => Controls_Manager::GALLERY,
  100. 'default' => [],
  101. 'show_label' => false,
  102. 'dynamic' => [
  103. 'active' => true,
  104. ],
  105. ]
  106. );
  107. $this->add_group_control(
  108. Group_Control_Image_Size::get_type(),
  109. [
  110. 'name' => 'thumbnail', // Usage: `{name}_size` and `{name}_custom_dimension`, in this case `thumbnail_size` and `thumbnail_custom_dimension`.
  111. 'separator' => 'none',
  112. ]
  113. );
  114. $slides_to_show = range( 1, 10 );
  115. $slides_to_show = array_combine( $slides_to_show, $slides_to_show );
  116. $this->add_responsive_control(
  117. 'slides_to_show',
  118. [
  119. 'label' => __( 'Slides to Show', 'elementor' ),
  120. 'type' => Controls_Manager::SELECT,
  121. 'options' => [
  122. '' => __( 'Default', 'elementor' ),
  123. ] + $slides_to_show,
  124. 'frontend_available' => true,
  125. ]
  126. );
  127. $this->add_control(
  128. 'slides_to_scroll',
  129. [
  130. 'label' => __( 'Slides to Scroll', 'elementor' ),
  131. 'type' => Controls_Manager::SELECT,
  132. 'description' => __( 'Set how many slides are scrolled per swipe.', 'elementor' ),
  133. 'default' => '2',
  134. 'options' => $slides_to_show,
  135. 'condition' => [
  136. 'slides_to_show!' => '1',
  137. ],
  138. 'frontend_available' => true,
  139. ]
  140. );
  141. $this->add_control(
  142. 'image_stretch',
  143. [
  144. 'label' => __( 'Image Stretch', 'elementor' ),
  145. 'type' => Controls_Manager::SELECT,
  146. 'default' => 'no',
  147. 'options' => [
  148. 'no' => __( 'No', 'elementor' ),
  149. 'yes' => __( 'Yes', 'elementor' ),
  150. ],
  151. ]
  152. );
  153. $this->add_control(
  154. 'navigation',
  155. [
  156. 'label' => __( 'Navigation', 'elementor' ),
  157. 'type' => Controls_Manager::SELECT,
  158. 'default' => 'both',
  159. 'options' => [
  160. 'both' => __( 'Arrows and Dots', 'elementor' ),
  161. 'arrows' => __( 'Arrows', 'elementor' ),
  162. 'dots' => __( 'Dots', 'elementor' ),
  163. 'none' => __( 'None', 'elementor' ),
  164. ],
  165. 'frontend_available' => true,
  166. ]
  167. );
  168. $this->add_control(
  169. 'link_to',
  170. [
  171. 'label' => __( 'Link to', 'elementor' ),
  172. 'type' => Controls_Manager::SELECT,
  173. 'default' => 'none',
  174. 'options' => [
  175. 'none' => __( 'None', 'elementor' ),
  176. 'file' => __( 'Media File', 'elementor' ),
  177. 'custom' => __( 'Custom URL', 'elementor' ),
  178. ],
  179. ]
  180. );
  181. $this->add_control(
  182. 'link',
  183. [
  184. 'label' => __( 'Link to', 'elementor' ),
  185. 'type' => Controls_Manager::URL,
  186. 'placeholder' => __( 'https://your-link.com', 'elementor' ),
  187. 'condition' => [
  188. 'link_to' => 'custom',
  189. ],
  190. 'show_label' => false,
  191. ]
  192. );
  193. $this->add_control(
  194. 'open_lightbox',
  195. [
  196. 'label' => __( 'Lightbox', 'elementor' ),
  197. 'type' => Controls_Manager::SELECT,
  198. 'default' => 'default',
  199. 'options' => [
  200. 'default' => __( 'Default', 'elementor' ),
  201. 'yes' => __( 'Yes', 'elementor' ),
  202. 'no' => __( 'No', 'elementor' ),
  203. ],
  204. 'condition' => [
  205. 'link_to' => 'file',
  206. ],
  207. ]
  208. );
  209. $this->add_control(
  210. 'caption_type',
  211. [
  212. 'label' => __( 'Caption', 'elementor' ),
  213. 'type' => Controls_Manager::SELECT,
  214. 'default' => '',
  215. 'options' => [
  216. '' => __( 'None', 'elementor' ),
  217. 'title' => __( 'Title', 'elementor' ),
  218. 'caption' => __( 'Caption', 'elementor' ),
  219. 'description' => __( 'Description', 'elementor' ),
  220. ],
  221. ]
  222. );
  223. $this->add_control(
  224. 'view',
  225. [
  226. 'label' => __( 'View', 'elementor' ),
  227. 'type' => Controls_Manager::HIDDEN,
  228. 'default' => 'traditional',
  229. ]
  230. );
  231. $this->end_controls_section();
  232. $this->start_controls_section(
  233. 'section_additional_options',
  234. [
  235. 'label' => __( 'Additional Options', 'elementor' ),
  236. ]
  237. );
  238. $this->add_control(
  239. 'pause_on_hover',
  240. [
  241. 'label' => __( 'Pause on Hover', 'elementor' ),
  242. 'type' => Controls_Manager::SELECT,
  243. 'default' => 'yes',
  244. 'options' => [
  245. 'yes' => __( 'Yes', 'elementor' ),
  246. 'no' => __( 'No', 'elementor' ),
  247. ],
  248. 'frontend_available' => true,
  249. ]
  250. );
  251. $this->add_control(
  252. 'autoplay',
  253. [
  254. 'label' => __( 'Autoplay', 'elementor' ),
  255. 'type' => Controls_Manager::SELECT,
  256. 'default' => 'yes',
  257. 'options' => [
  258. 'yes' => __( 'Yes', 'elementor' ),
  259. 'no' => __( 'No', 'elementor' ),
  260. ],
  261. 'frontend_available' => true,
  262. ]
  263. );
  264. $this->add_control(
  265. 'autoplay_speed',
  266. [
  267. 'label' => __( 'Autoplay Speed', 'elementor' ),
  268. 'type' => Controls_Manager::NUMBER,
  269. 'default' => 5000,
  270. 'frontend_available' => true,
  271. ]
  272. );
  273. $this->add_control(
  274. 'infinite',
  275. [
  276. 'label' => __( 'Infinite Loop', 'elementor' ),
  277. 'type' => Controls_Manager::SELECT,
  278. 'default' => 'yes',
  279. 'options' => [
  280. 'yes' => __( 'Yes', 'elementor' ),
  281. 'no' => __( 'No', 'elementor' ),
  282. ],
  283. 'frontend_available' => true,
  284. ]
  285. );
  286. $this->add_control(
  287. 'effect',
  288. [
  289. 'label' => __( 'Effect', 'elementor' ),
  290. 'type' => Controls_Manager::SELECT,
  291. 'default' => 'slide',
  292. 'options' => [
  293. 'slide' => __( 'Slide', 'elementor' ),
  294. 'fade' => __( 'Fade', 'elementor' ),
  295. ],
  296. 'condition' => [
  297. 'slides_to_show' => '1',
  298. ],
  299. 'frontend_available' => true,
  300. ]
  301. );
  302. $this->add_control(
  303. 'speed',
  304. [
  305. 'label' => __( 'Animation Speed', 'elementor' ),
  306. 'type' => Controls_Manager::NUMBER,
  307. 'default' => 500,
  308. 'frontend_available' => true,
  309. ]
  310. );
  311. $this->add_control(
  312. 'direction',
  313. [
  314. 'label' => __( 'Direction', 'elementor' ),
  315. 'type' => Controls_Manager::SELECT,
  316. 'default' => 'ltr',
  317. 'options' => [
  318. 'ltr' => __( 'Left', 'elementor' ),
  319. 'rtl' => __( 'Right', 'elementor' ),
  320. ],
  321. 'frontend_available' => true,
  322. ]
  323. );
  324. $this->end_controls_section();
  325. $this->start_controls_section(
  326. 'section_style_navigation',
  327. [
  328. 'label' => __( 'Navigation', 'elementor' ),
  329. 'tab' => Controls_Manager::TAB_STYLE,
  330. 'condition' => [
  331. 'navigation' => [ 'arrows', 'dots', 'both' ],
  332. ],
  333. ]
  334. );
  335. $this->add_control(
  336. 'heading_style_arrows',
  337. [
  338. 'label' => __( 'Arrows', 'elementor' ),
  339. 'type' => Controls_Manager::HEADING,
  340. 'separator' => 'before',
  341. 'condition' => [
  342. 'navigation' => [ 'arrows', 'both' ],
  343. ],
  344. ]
  345. );
  346. $this->add_control(
  347. 'arrows_position',
  348. [
  349. 'label' => __( 'Position', 'elementor' ),
  350. 'type' => Controls_Manager::SELECT,
  351. 'default' => 'inside',
  352. 'options' => [
  353. 'inside' => __( 'Inside', 'elementor' ),
  354. 'outside' => __( 'Outside', 'elementor' ),
  355. ],
  356. 'condition' => [
  357. 'navigation' => [ 'arrows', 'both' ],
  358. ],
  359. ]
  360. );
  361. $this->add_control(
  362. 'arrows_size',
  363. [
  364. 'label' => __( 'Size', 'elementor' ),
  365. 'type' => Controls_Manager::SLIDER,
  366. 'range' => [
  367. 'px' => [
  368. 'min' => 20,
  369. 'max' => 60,
  370. ],
  371. ],
  372. 'selectors' => [
  373. '{{WRAPPER}} .elementor-image-carousel-wrapper .slick-slider .slick-prev:before, {{WRAPPER}} .elementor-image-carousel-wrapper .slick-slider .slick-next:before' => 'font-size: {{SIZE}}{{UNIT}};',
  374. ],
  375. 'condition' => [
  376. 'navigation' => [ 'arrows', 'both' ],
  377. ],
  378. ]
  379. );
  380. $this->add_control(
  381. 'arrows_color',
  382. [
  383. 'label' => __( 'Color', 'elementor' ),
  384. 'type' => Controls_Manager::COLOR,
  385. 'selectors' => [
  386. '{{WRAPPER}} .elementor-image-carousel-wrapper .slick-slider .slick-prev:before, {{WRAPPER}} .elementor-image-carousel-wrapper .slick-slider .slick-next:before' => 'color: {{VALUE}};',
  387. ],
  388. 'condition' => [
  389. 'navigation' => [ 'arrows', 'both' ],
  390. ],
  391. ]
  392. );
  393. $this->add_control(
  394. 'heading_style_dots',
  395. [
  396. 'label' => __( 'Dots', 'elementor' ),
  397. 'type' => Controls_Manager::HEADING,
  398. 'separator' => 'before',
  399. 'condition' => [
  400. 'navigation' => [ 'dots', 'both' ],
  401. ],
  402. ]
  403. );
  404. $this->add_control(
  405. 'dots_position',
  406. [
  407. 'label' => __( 'Position', 'elementor' ),
  408. 'type' => Controls_Manager::SELECT,
  409. 'default' => 'outside',
  410. 'options' => [
  411. 'outside' => __( 'Outside', 'elementor' ),
  412. 'inside' => __( 'Inside', 'elementor' ),
  413. ],
  414. 'condition' => [
  415. 'navigation' => [ 'dots', 'both' ],
  416. ],
  417. ]
  418. );
  419. $this->add_control(
  420. 'dots_size',
  421. [
  422. 'label' => __( 'Size', 'elementor' ),
  423. 'type' => Controls_Manager::SLIDER,
  424. 'range' => [
  425. 'px' => [
  426. 'min' => 5,
  427. 'max' => 10,
  428. ],
  429. ],
  430. 'selectors' => [
  431. '{{WRAPPER}} .elementor-image-carousel-wrapper .elementor-image-carousel .slick-dots li button:before' => 'font-size: {{SIZE}}{{UNIT}};',
  432. ],
  433. 'condition' => [
  434. 'navigation' => [ 'dots', 'both' ],
  435. ],
  436. ]
  437. );
  438. $this->add_control(
  439. 'dots_color',
  440. [
  441. 'label' => __( 'Color', 'elementor' ),
  442. 'type' => Controls_Manager::COLOR,
  443. 'selectors' => [
  444. '{{WRAPPER}} .elementor-image-carousel-wrapper .elementor-image-carousel .slick-dots li button:before' => 'color: {{VALUE}};',
  445. ],
  446. 'condition' => [
  447. 'navigation' => [ 'dots', 'both' ],
  448. ],
  449. ]
  450. );
  451. $this->end_controls_section();
  452. $this->start_controls_section(
  453. 'section_style_image',
  454. [
  455. 'label' => __( 'Image', 'elementor' ),
  456. 'tab' => Controls_Manager::TAB_STYLE,
  457. ]
  458. );
  459. $this->add_control(
  460. 'image_spacing',
  461. [
  462. 'label' => __( 'Spacing', 'elementor' ),
  463. 'type' => Controls_Manager::SELECT,
  464. 'options' => [
  465. '' => __( 'Default', 'elementor' ),
  466. 'custom' => __( 'Custom', 'elementor' ),
  467. ],
  468. 'default' => '',
  469. 'condition' => [
  470. 'slides_to_show!' => '1',
  471. ],
  472. ]
  473. );
  474. $this->add_control(
  475. 'image_spacing_custom',
  476. [
  477. 'label' => __( 'Image Spacing', 'elementor' ),
  478. 'type' => Controls_Manager::SLIDER,
  479. 'range' => [
  480. 'px' => [
  481. 'max' => 100,
  482. ],
  483. ],
  484. 'default' => [
  485. 'size' => 20,
  486. ],
  487. 'show_label' => false,
  488. 'selectors' => [
  489. '{{WRAPPER}} .slick-list' => 'margin-left: -{{SIZE}}{{UNIT}};',
  490. '{{WRAPPER}} .slick-slide .slick-slide-inner' => 'padding-left: {{SIZE}}{{UNIT}};',
  491. ],
  492. 'condition' => [
  493. 'image_spacing' => 'custom',
  494. 'slides_to_show!' => '1',
  495. ],
  496. ]
  497. );
  498. $this->add_group_control(
  499. Group_Control_Border::get_type(),
  500. [
  501. 'name' => 'image_border',
  502. 'selector' => '{{WRAPPER}} .elementor-image-carousel-wrapper .elementor-image-carousel .slick-slide-image',
  503. 'separator' => 'before',
  504. ]
  505. );
  506. $this->add_control(
  507. 'image_border_radius',
  508. [
  509. 'label' => __( 'Border Radius', 'elementor' ),
  510. 'type' => Controls_Manager::DIMENSIONS,
  511. 'size_units' => [ 'px', '%' ],
  512. 'selectors' => [
  513. '{{WRAPPER}} .elementor-image-carousel-wrapper .elementor-image-carousel .slick-slide-image' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
  514. ],
  515. ]
  516. );
  517. $this->end_controls_section();
  518. $this->start_controls_section(
  519. 'section_caption',
  520. [
  521. 'label' => __( 'Caption', 'elementor' ),
  522. 'tab' => Controls_Manager::TAB_STYLE,
  523. 'condition' => [
  524. 'caption_type!' => '',
  525. ],
  526. ]
  527. );
  528. $this->add_control(
  529. 'caption_align',
  530. [
  531. 'label' => __( 'Alignment', 'elementor' ),
  532. 'type' => Controls_Manager::CHOOSE,
  533. 'options' => [
  534. 'left' => [
  535. 'title' => __( 'Left', 'elementor' ),
  536. 'icon' => 'fa fa-align-left',
  537. ],
  538. 'center' => [
  539. 'title' => __( 'Center', 'elementor' ),
  540. 'icon' => 'fa fa-align-center',
  541. ],
  542. 'right' => [
  543. 'title' => __( 'Right', 'elementor' ),
  544. 'icon' => 'fa fa-align-right',
  545. ],
  546. 'justify' => [
  547. 'title' => __( 'Justified', 'elementor' ),
  548. 'icon' => 'fa fa-align-justify',
  549. ],
  550. ],
  551. 'default' => 'center',
  552. 'selectors' => [
  553. '{{WRAPPER}} .elementor-image-carousel-caption' => 'text-align: {{VALUE}};',
  554. ],
  555. ]
  556. );
  557. $this->add_control(
  558. 'caption_text_color',
  559. [
  560. 'label' => __( 'Text Color', 'elementor' ),
  561. 'type' => Controls_Manager::COLOR,
  562. 'default' => '',
  563. 'selectors' => [
  564. '{{WRAPPER}} .elementor-image-carousel-caption' => 'color: {{VALUE}};',
  565. ],
  566. ]
  567. );
  568. $this->add_group_control(
  569. Group_Control_Typography::get_type(),
  570. [
  571. 'name' => 'caption_typography',
  572. 'scheme' => Scheme_Typography::TYPOGRAPHY_4,
  573. 'selector' => '{{WRAPPER}} .elementor-image-carousel-caption',
  574. ]
  575. );
  576. $this->end_controls_section();
  577. }
  578. /**
  579. * Render image carousel widget output on the frontend.
  580. *
  581. * Written in PHP and used to generate the final HTML.
  582. *
  583. * @since 1.0.0
  584. * @access protected
  585. */
  586. protected function render() {
  587. $settings = $this->get_settings_for_display();
  588. if ( empty( $settings['carousel'] ) ) {
  589. return;
  590. }
  591. $slides = [];
  592. foreach ( $settings['carousel'] as $index => $attachment ) {
  593. $image_url = Group_Control_Image_Size::get_attachment_image_src( $attachment['id'], 'thumbnail', $settings );
  594. $image_html = '<img class="slick-slide-image" src="' . esc_attr( $image_url ) . '" alt="' . esc_attr( Control_Media::get_image_alt( $attachment ) ) . '" />';
  595. $link = $this->get_link_url( $attachment, $settings );
  596. if ( $link ) {
  597. $link_key = 'link_' . $index;
  598. $this->add_render_attribute( $link_key, [
  599. 'href' => $link['url'],
  600. 'data-elementor-open-lightbox' => $settings['open_lightbox'],
  601. 'data-elementor-lightbox-slideshow' => $this->get_id(),
  602. 'data-elementor-lightbox-index' => $index,
  603. ] );
  604. if ( Plugin::$instance->editor->is_edit_mode() ) {
  605. $this->add_render_attribute( $link_key, [
  606. 'class' => 'elementor-clickable',
  607. ] );
  608. }
  609. if ( ! empty( $link['is_external'] ) ) {
  610. $this->add_render_attribute( $link_key, 'target', '_blank' );
  611. }
  612. if ( ! empty( $link['nofollow'] ) ) {
  613. $this->add_render_attribute( $link_key, 'rel', 'nofollow' );
  614. }
  615. $image_html = '<a ' . $this->get_render_attribute_string( $link_key ) . '>' . $image_html . '</a>';
  616. }
  617. $image_caption = $this->get_image_caption( $attachment );
  618. $slide_html = '<div class="slick-slide"><figure class="slick-slide-inner">' . $image_html;
  619. if ( ! empty( $image_caption ) ) {
  620. $slide_html .= '<figcaption class="elementor-image-carousel-caption">' . $image_caption . '</figcaption>';
  621. }
  622. $slide_html .= '</figure></div>';
  623. $slides[] = $slide_html;
  624. }
  625. if ( empty( $slides ) ) {
  626. return;
  627. }
  628. $this->add_render_attribute( 'carousel', 'class', 'elementor-image-carousel' );
  629. if ( 'none' !== $settings['navigation'] ) {
  630. if ( 'dots' !== $settings['navigation'] ) {
  631. $this->add_render_attribute( 'carousel', 'class', 'slick-arrows-' . $settings['arrows_position'] );
  632. }
  633. if ( 'arrows' !== $settings['navigation'] ) {
  634. $this->add_render_attribute( 'carousel', 'class', 'slick-dots-' . $settings['dots_position'] );
  635. }
  636. }
  637. if ( 'yes' === $settings['image_stretch'] ) {
  638. $this->add_render_attribute( 'carousel', 'class', 'slick-image-stretch' );
  639. }
  640. ?>
  641. <div class="elementor-image-carousel-wrapper elementor-slick-slider" dir="<?php echo $settings['direction']; ?>">
  642. <div <?php echo $this->get_render_attribute_string( 'carousel' ); ?>>
  643. <?php echo implode( '', $slides ); ?>
  644. </div>
  645. </div>
  646. <?php
  647. }
  648. /**
  649. * Retrieve image carousel link URL.
  650. *
  651. * @since 1.0.0
  652. * @access private
  653. *
  654. * @param array $attachment
  655. * @param object $instance
  656. *
  657. * @return array|string|false An array/string containing the attachment URL, or false if no link.
  658. */
  659. private function get_link_url( $attachment, $instance ) {
  660. if ( 'none' === $instance['link_to'] ) {
  661. return false;
  662. }
  663. if ( 'custom' === $instance['link_to'] ) {
  664. if ( empty( $instance['link']['url'] ) ) {
  665. return false;
  666. }
  667. return $instance['link'];
  668. }
  669. return [
  670. 'url' => wp_get_attachment_url( $attachment['id'] ),
  671. ];
  672. }
  673. /**
  674. * Retrieve image carousel caption.
  675. *
  676. * @since 1.2.0
  677. * @access private
  678. *
  679. * @param array $attachment
  680. *
  681. * @return string The caption of the image.
  682. */
  683. private function get_image_caption( $attachment ) {
  684. $caption_type = $this->get_settings_for_display( 'caption_type' );
  685. if ( empty( $caption_type ) ) {
  686. return '';
  687. }
  688. $attachment_post = get_post( $attachment['id'] );
  689. if ( 'caption' === $caption_type ) {
  690. return $attachment_post->post_excerpt;
  691. }
  692. if ( 'title' === $caption_type ) {
  693. return $attachment_post->post_title;
  694. }
  695. return $attachment_post->post_content;
  696. }
  697. }