1: <?php
2:
3: namespace RedBeanPHP;
4:
5: use RedBeanPHP\ToolBox as ToolBox;
6: use RedBeanPHP\OODBBean as OODBBean;
7:
8: /**
9: * Label Maker.
10: * Makes so-called label beans.
11: * A label is a bean with only an id, type and name property.
12: * Labels can be used to create simple entities like categories, tags or enums.
13: * This service class provides convenience methods to deal with this kind of
14: * beans.
15: *
16: * @file RedBeanPHP/LabelMaker.php
17: * @author Gabor de Mooij and the RedBeanPHP Community
18: * @license BSD/GPLv2
19: *
20: * @copyright
21: * copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
22: * This source file is subject to the BSD/GPLv2 License that is bundled
23: * with this source code in the file license.txt.
24: */
25: class LabelMaker
26: {
27: /**
28: * @var ToolBox
29: */
30: protected $toolbox;
31:
32: /**
33: * Constructor.
34: *
35: * @param ToolBox $toolbox
36: */
37: public function __construct( ToolBox $toolbox )
38: {
39: $this->toolbox = $toolbox;
40: }
41:
42: /**
43: * A label is a bean with only an id, type and name property.
44: * This function will dispense beans for all entries in the array. The
45: * values of the array will be assigned to the name property of each
46: * individual bean.
47: *
48: * <code>
49: * $people = R::dispenseLabels( 'person', [ 'Santa', 'Claus' ] );
50: * </code>
51: *
52: * @param string $type type of beans you would like to have
53: * @param array $labels list of labels, names for each bean
54: *
55: * @return array
56: */
57: public function dispenseLabels( $type, $labels )
58: {
59: $labelBeans = array();
60: foreach ( $labels as $label ) {
61: $labelBean = $this->toolbox->getRedBean()->dispense( $type );
62: $labelBean->name = $label;
63: $labelBeans[] = $labelBean;
64: }
65:
66: return $labelBeans;
67: }
68:
69: /**
70: * Gathers labels from beans. This function loops through the beans,
71: * collects the value of the name property for each individual bean
72: * and stores the names in a new array. The array then gets sorted using the
73: * default sort function of PHP (sort).
74: *
75: * Usage:
76: *
77: * <code>
78: * $o1->name = 'hamburger';
79: * $o2->name = 'pizza';
80: * implode( ',', R::gatherLabels( [ $o1, $o2 ] ) ); //hamburger,pizza
81: * </code>
82: *
83: * Note that the return value is an array of strings, not beans.
84: *
85: * @param array $beans list of beans to loop through
86: *
87: * @return array
88: */
89: public function gatherLabels( $beans )
90: {
91: $labels = array();
92:
93: foreach ( $beans as $bean ) {
94: $labels[] = $bean->name;
95: }
96:
97: sort( $labels );
98:
99: return $labels;
100: }
101:
102: /**
103: * Fetches an ENUM from the database and creates it if necessary.
104: * An ENUM has the following format:
105: *
106: * <code>
107: * ENUM:VALUE
108: * </code>
109: *
110: * If you pass 'ENUM' only, this method will return an array of its
111: * values:
112: *
113: * <code>
114: * implode( ',', R::gatherLabels( R::enum( 'flavour' ) ) ) //'BANANA,MOCCA'
115: * </code>
116: *
117: * If you pass 'ENUM:VALUE' this method will return the specified enum bean
118: * and create it in the database if it does not exist yet:
119: *
120: * <code>
121: * $bananaFlavour = R::enum( 'flavour:banana' );
122: * $bananaFlavour->name;
123: * </code>
124: *
125: * So you can use this method to set an ENUM value in a bean:
126: *
127: * <code>
128: * $shake->flavour = R::enum( 'flavour:banana' );
129: * </code>
130: *
131: * the property flavour now contains the enum bean, a parent bean.
132: * In the database, flavour_id will point to the flavour record with name 'banana'.
133: *
134: * @param string $enum ENUM specification for label
135: *
136: * @return array|OODBBean
137: */
138: public function enum( $enum )
139: {
140: $oodb = $this->toolbox->getRedBean();
141:
142: if ( strpos( $enum, ':' ) === FALSE ) {
143: $type = $enum;
144: $value = FALSE;
145: } else {
146: list( $type, $value ) = explode( ':', $enum );
147: $value = preg_replace( '/\W+/', '_', strtoupper( trim( $value ) ) );
148: }
149:
150: /**
151: * We use simply find here, we could use inspect() in fluid mode etc,
152: * but this would be useless. At first sight it looks clean, you could even
153: * bake this into find(), however, find not only has to deal with the primary
154: * search type, people can also include references in the SQL part, so avoiding
155: * find failures does not matter, this is still the quickest way making use
156: * of existing functionality.
157: *
158: * @note There seems to be a bug in XDebug v2.3.2 causing suppressed
159: * exceptions like these to surface anyway, to prevent this use:
160: *
161: * "xdebug.default_enable = 0"
162: *
163: * Also see Github Issue #464
164: */
165: $values = $oodb->find( $type );
166:
167: if ( $value === FALSE ) {
168: return $values;
169: }
170:
171: foreach( $values as $enumItem ) {
172: if ( $enumItem->name === $value ) return $enumItem;
173: }
174:
175: $newEnumItems = $this->dispenseLabels( $type, array( $value ) );
176: $newEnumItem = reset( $newEnumItems );
177:
178: $oodb->store( $newEnumItem );
179:
180: return $newEnumItem;
181: }
182: }
183: