@@ -535,6 +535,77 @@ public function create()
535535 */
536536 return $ this ->_postSave (self ::$ _disableEvents , $ success , false );
537537 }
538+
539+ /**
540+ * {@inheritdoc}
541+ *
542+ * @param array $data
543+ */
544+ public function createIfNotExist (array $ criteria )
545+ {
546+ if (empty ($ criteria )) {
547+ throw new Exception ("Criteria parameter must be array with one or more attributes of the model " );
548+ }
549+
550+ /**
551+ * Choose a collection according to the collection name
552+ */
553+ $ collection = $ this ->prepareCU ();
554+
555+ /**
556+ * Assume non-existence to fire beforeCreate events - no update does occur anyway
557+ */
558+ $ exists = false ;
559+
560+ /**
561+ * Reset current operation
562+ */
563+ $ this ->_operationMade = self ::OP_NONE ;
564+
565+ /**
566+ * The messages added to the validator are reset here
567+ */
568+ $ this ->_errorMessages = [];
569+
570+ /**
571+ * Execute the preSave hook
572+ */
573+ if ($ this ->_preSave ($ this ->_dependencyInjector , self ::$ _disableEvents , $ exists ) === false ) {
574+ return false ;
575+ }
576+
577+ $ keys = array_flip ($ criteria );
578+ $ data = $ this ->toArray ();
579+
580+ if (array_diff_key ($ keys , $ data )) {
581+ throw new \Exception ("Criteria parameter must be array with one or more attributes of the model " );
582+ }
583+
584+ $ query = array_intersect_key ($ data , $ keys );
585+
586+ $ success = false ;
587+
588+ $ status = $ collection ->findOneAndUpdate ($ query ,
589+ ['$setOnInsert ' => $ data ],
590+ ['new ' => true , 'upsert ' => true ]);
591+
592+ if ($ status == null ) {
593+ $ doc = $ collection ->findOne ($ query );
594+
595+ if (is_object ($ doc )) {
596+ $ success = true ;
597+ $ this ->_operationMade = self ::OP_CREATE ;
598+ $ this ->_id = $ doc ['_id ' ];
599+ }
600+ } else {
601+ $ this ->appendMessage (new Message ("Document already exists " ));
602+ }
603+
604+ /**
605+ * Call the postSave hooks
606+ */
607+ return $ this ->_postSave (self ::$ _disableEvents , $ success , $ exists );
608+ }
538609
539610 /**
540611 * {@inheritdoc}
0 commit comments