1: <?php
  2: 
  3: /**
  4:  * @copyright Copyright (c) 2009-2022 ThemeCatcher (https://www.themecatcher.net)
  5:  */
  6: abstract class Quform_Element_Container extends Quform_Element
  7: {
  8:     /**
  9:      * The child elements of this container
 10:      * @var Quform_Element[]
 11:      */
 12:     protected $elements = array();
 13: 
 14:     /**
 15:      * Whether the container contains at least one non-empty child element, this will be processed and set when processing the form
 16:      * @var boolean
 17:      */
 18:     protected $hasNonEmptyChild = false;
 19: 
 20:     /**
 21:      * Whether the container contains at least one conditionally visible child element, this will be processed and set when processing the form
 22:      * @var boolean
 23:      */
 24:     protected $hasVisibleChild = false;
 25: 
 26:     /**
 27:      * Get the child elements of this element
 28:      *
 29:      * @return Quform_Element[] The form elements
 30:      */
 31:     public function getElements()
 32:     {
 33:         return $this->elements;
 34:     }
 35: 
 36:     /**
 37:      * Add a form element to the container
 38:      *
 39:      * @param Quform_Element $element
 40:      */
 41:     public function addElement(Quform_Element $element)
 42:     {
 43:         $this->elements[$element->getName()] = $element;
 44:     }
 45: 
 46:     /**
 47:      * Get the HTML for the title and description
 48:      *
 49:      * @return  string
 50:      */
 51:     protected function getTitleDescriptionHtml()
 52:     {
 53:         $output = '';
 54:         $title = $this->config('title');
 55:         $description = $this->config('description');
 56:         $showTitle = Quform::isNonEmptyString($title);
 57:         $showDescription = Quform::isNonEmptyString($description);
 58: 
 59:         switch (get_class($this)) {
 60:             case 'Quform_Element_Page':
 61:                 $prefix = 'page';
 62:                 break;
 63:             case 'Quform_Element_Group':
 64:                 $prefix = 'group';
 65:                 break;
 66:         }
 67: 
 68:         if ($showTitle || $showDescription) {
 69:             $output .= sprintf('<div class="quform-%s-title-description">', $prefix);
 70: 
 71:             if ($showTitle) {
 72:                 $output .= Quform::getHtmlTag($this->config('titleTag'), array('class' => sprintf('quform-%s-title', $prefix)), do_shortcode($title));
 73:             }
 74: 
 75:             if ($showDescription) {
 76:                 $output .= Quform::getHtmlTag('p', array('class' => sprintf('quform-%s-description', $prefix)), do_shortcode($description));
 77:             }
 78: 
 79:             $output .= '</div>';
 80:         }
 81: 
 82:         return $output;
 83:     }
 84: 
 85:     /**
 86:      * @return array
 87:      */
 88:     abstract protected function getContainerClasses();
 89: 
 90:     /**
 91:      * Render the CSS for this container and its children
 92:      *
 93:      * @param   array   $context
 94:      * @return  string
 95:      */
 96:     protected function renderCss(array $context = array())
 97:     {
 98:         $css = '';
 99: 
100:         foreach ($this->elements as $element) {
101:             $css .= $element->getCss($context);
102:         }
103: 
104:         $css .= parent::renderCss($context);
105: 
106:         return $css;
107:     }
108: 
109:     /**
110:      * Set whether the container contains at least one non-empty child element, this will be processed and set when processing the form
111:      *
112:      * @param boolean $flag
113:      */
114:     public function setHasNonEmptyChild($flag)
115:     {
116:         $this->hasNonEmptyChild = (bool) $flag;
117:     }
118: 
119:     /**
120:      * Set whether the container contains at least one conditionally visible child element
121:      *
122:      * @param boolean $flag
123:      */
124:     public function setHasVisibleChild($flag)
125:     {
126:         $this->hasVisibleChild = (bool) $flag;
127:     }
128: 
129:     /**
130:      * Get whether the container contains at least one conditionally visible child element
131:      *
132:      * @return boolean
133:      */
134:     public function getHasVisibleChild()
135:     {
136:         return $this->hasVisibleChild;
137:     }
138: 
139:     /**
140:      * Get whether the container is empty
141:      *
142:      * @return boolean
143:      */
144:     public function isEmpty()
145:     {
146:         return ! $this->hasNonEmptyChild;
147:     }
148: 
149:     /**
150:      * Get whether the container is hidden
151:      *
152:      * @return boolean
153:      */
154:     public function isHidden()
155:     {
156:         return $this->isConditionallyHidden() || ! $this->hasVisibleChild;
157:     }
158: 
159:     /**
160:      * Get the recursive iterator to iterate over the form elements
161:      *
162:      * Modes:
163:      * RecursiveIteratorIterator::LEAVES_ONLY
164:      * RecursiveIteratorIterator::SELF_FIRST
165:      * RecursiveIteratorIterator::CHILD_FIRST
166:      * RecursiveIteratorIterator::CATCH_GET_CHILD
167:      *
168:      * @param  int $mode
169:      * @return RecursiveIteratorIterator
170:      */
171:     public function getRecursiveIterator($mode = RecursiveIteratorIterator::LEAVES_ONLY)
172:     {
173:         return new RecursiveIteratorIterator(
174:             new Quform_Element_Container_Iterator($this),
175:             $mode
176:         );
177:     }
178: }
179: