Invision Community 4: SEO, prepare for v5 and dormant account notifications By Matt Monday at 02:04 PM
BomAle Posted November 20, 2016 Posted November 20, 2016 Hello, I have tested with @Joel R website and localhost the plugin Chatbox Extender and Rules app and I have intercepted an error, but i don't know if it must be fixed by @Kevin Carwile or IPS Staff. I leave some screenshot
Joel R Posted November 20, 2016 Posted November 20, 2016 Did you submit a support ticket for this? Otherwise IPS might ignore ...
BomAle Posted November 20, 2016 Author Posted November 20, 2016 I hook into save function because some devs use createItem(...) and save() (instead of createFromForm(...)) and none of them have processAfterCreate() like createFromForm() has.
BomAle Posted November 21, 2016 Author Posted November 21, 2016 unless I will try this code /*it was a new item?*/ if($this->_new) { $this->ce_new = TRUE; } /*call here parent save*/ /*avoid sendtochatbox if save is called into processForm*/ if($this->ce_new AND !in_array('processForm', array_map( function ($v) { return $v['function']; }, debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) ))) { $this->sendtochatbox(); } but i think this is not a performance way...
BomAle Posted November 22, 2016 Author Posted November 22, 2016 @bfarber @Ryan Ashbrook @Matt @Mark please take a look on this.
Management Matt Posted November 22, 2016 Management Posted November 22, 2016 I'll take a look tomorrow. (If this post gets 5 likes).
bfarber Posted November 23, 2016 Posted November 23, 2016 I'm really not clear the issue off the top of my head just looking at your code. It appears that you are hooking into the save() method, but when processForm() calls it to set the ID it's causing an issue. Without sitting there with both things installed and investigating what the conflict is though, I'm not sure what to suggest specifically I'm afraid.
BomAle Posted November 23, 2016 Author Posted November 23, 2016 @bfarber some developer don't call processAfterCreate() after create a item. in code. The docs don't tell nothing about this but I think it is a general miss that could be solved only with knowledge all developers to call this. processForm( array $values )Immediately after processBeforeCreate(), this method is ran. It differs from processAfterCreate() in that it runs for edits as well as new items. You should use it to set any fields you added in formElements() which are more complicated than just setting the direct value (which would be done automatically). The default method sets the title, tags (if enabled - see Tags section) and other data, so ensure you call the method in the parent class to not override this. processAfterCreate( \IPS\Content\Comment$comment=NULL, array $values )After the content item has been inserted into the database and all processing has done, including creating the first comment if enabled (see chapter 3), this method is ran. It receives an object for the first comment if applicable and the values from the form. also processBeforeCreate is not used... @Adriano Faria @Mike John in forms app...
Marcher Technologies Posted November 23, 2016 Posted November 23, 2016 2 hours ago, BomAle said: @bfarber some developer don't call processAfterCreate() after create a item. in code. The docs don't tell nothing about this but I think it is a general miss that could be solved only with knowledge all developers to call this. That's not what that method is for. On 11/20/2016 at 4:52 AM, BomAle said: I hook into save function because some devs use createItem(...) and save() (instead of createFromForm(...)) and none of them have processAfterCreate() like createFromForm() has. createFromForm(and as a result, processAfterCreate) is used exclusively by the automated controller which needs something to handle processing after creation automatically. The core does not use these methods when the automated controller is not used, for example on RSS Import. Hopefully that clarifies.
BomAle Posted November 23, 2016 Author Posted November 23, 2016 1 hour ago, Marcher Technologies said: The core does not use these methods when the automated controller is not used, for example on RSS Import. Indeed, if still someone wanted to track when a topic is correctly create (with a comment if first post is required) regardless of the case in which it is generated how should I do? I think I arrived at a dead point now, I do not know it is clear. /* ON RSS IMPORT */ $topic = \IPS\forums\Topic::createItem( \IPS\Member::load( $this->mid ), NULL, $article['date'], $container, $this->topic_hide ); $topic->title = $this->topic_pre . $article['title']; if ( !$this->topic_open ) { $topic->state = 'closed'; } /* FIRST CALL... NOT OK :( */ $topic->save(); .......... $post = \IPS\forums\Topic\Post::create( $topic, $content, TRUE, NULL, \IPS\forums\Topic\Post::incrementPostCount( $container ), $member, $article['date'] ); $topic->topic_firstpost = $post->pid; /* SECOND CALL... OK, HOW I FETCH LAST CALL?*/ $topic->save();
Marcher Technologies Posted November 23, 2016 Posted November 23, 2016 You are not on the wrong track with keeping a copy of the _new state around in the object. Best option would be to do that, then do nothing in the save method, the first time it's called, ie your variable is false/not set. If the custom _new variable is true AND topic_firstpost is set, do what you need to do and set the custom _new variable copy back to false. /* was this a new topic and is the first post now present? */ if($this->ce_new && $this->topic_firstpost) { /*do the stuff you need to do*/ $this->ce_new = FALSE; } /*is this a new topic?*/ if($this->_new) { $this->ce_new = TRUE; } parent::save(); be sure to define the ce_new variable locally in the hook so the ActiveRecord doesn't try to save it to the database.
Daniel F Posted November 23, 2016 Posted November 23, 2016 1 minute ago, BomAle said: Indeed, if still someone wanted to track when a topic is correctly create I can't see why using the save method would be wrong... ( Private 0.02$ => I'm using it for all my stuff.. ) Personally i would use something like... if ( ( $this->_new AND !$this->isFutureDate() AND $this->hidden() ) OR ( ... some other conditions to verify it was e.g. hidden and became now visible..) ) { //run your code ... }
BomAle Posted November 23, 2016 Author Posted November 23, 2016 because some params could be defined after first call of save like "topic_firstpost"... if i try to get $item->url() for any item like into statuses and suppose url() return as: $this->_url = \IPS\Http\Url::internal( "app=core&module=members&controller=profile&id={$member->member_id}&status={$this->id}&type=status&firstpost={$this->topic_firstpost}", 'front', 'profile', array( $member->members_seo_name ) ); id=0 and firstpost=0 the param $this->topic_firstpost is not yet inserted it is empty or default... ( see first post image in this topic processForm ) and url could be not as expected. I was thinking of not having to do so in order to check the url() function for each item ...considering that some devs could change it as they want. I already check item status (hidden future date into 1.0.6 chatbox extender).
Daniel F Posted November 23, 2016 Posted November 23, 2016 Then you could and IMO should hook at the comment class instead of the in combination with a isFirst() check ! (my private minds, not an official answer)
Daniel F Posted November 23, 2016 Posted November 23, 2016 @5 finger @Matt just say that I'm right. Thx
BomAle Posted February 18, 2017 Author Posted February 18, 2017 On 23/11/2016 at 8:13 PM, Marcher Technologies said: You are not on the wrong track with keeping a copy of the _new state around in the object. Best option would be to do that, then do nothing in the save method, the first time it's called, ie your variable is false/not set. If the custom _new variable is true AND topic_firstpost is set, do what you need to do and set the custom _new variable copy back to false. /* was this a new topic and is the first post now present? */ if($this->ce_new && $this->topic_firstpost) { /*do the stuff you need to do*/ $this->ce_new = FALSE; } /*is this a new topic?*/ if($this->_new) { $this->ce_new = TRUE; } parent::save(); be sure to define the ce_new variable locally in the hook so the ActiveRecord doesn't try to save it to the database. THANKS, now i wait fix for: /* Work out which profile we are posting too, but only if we are NOT coming from the Create menu or the status updates widget (neither of which allow posting to another profile */ /* @todo The dependency on \IPS\Request here needs to be moved to the controller */ $this->member_id = ( isset( \IPS\Request::i()->id ) AND ( isset( \IPS\Request::i()->controller ) AND \IPS\Request::i()->controller != 'ajaxcreate' ) ) ? \IPS\Request::i()->id : \IPS\Member::loggedIn()->member_id; or I must check for status var for temporary solve. @Matt /** * @brief Remember _new status on subsequent calls */ protected $ceNew = NULL; /** * Save Changed Columns * * @see \IPS\Content\Item::save() * * @return void */ public function save() { if( $this->_new ) { $this->ceNew = TRUE; } call_user_func_array( 'parent::save', func_get_args() ); $idColumn = static::$databaseColumnId; /*CHECKs for approval item onUnhide, future date onPublish...*/ if ( !$this->ceNew OR $this->hidden() OR $this->isFutureDate() OR !$this->$idColumn ) { return; } $this->sendToChatbox(); $this->ceNew = FALSE; }
Recommended Posts
Archived
This topic is now archived and is closed to further replies.