alternativen zu hook\_init ()
<p>ich benutze <code>hook\_init()</code>, um die letzte zugriffszeit der benutzer zu überprüfen. wenn die letzte zugriffszeit gestern ist, erhöhe ich einen zähler und setze einige variablen.</p><p>das problem ist, dass <code>hook\_init()</code> manchmal mehr als einmal ausgeführt wird (ich kann dies mit <code>dsm()</code> sehen), wenn dieselbe seite geladen wird, sodass mein code mehrmals ausgeführt wird, was zu falschen variablen führt.</p><p>warum wird <code>hook\_init()</code> mehrmals ausgeführt?<br> was wäre der beste ansatz für mein problem? soll ich einen anderen haken verwenden?</p><p><strong>ich habe etwas mehr darüber gegraben :</strong> ich suche nach aufrufen von hook\_init () (gesucht nach zeichenfolge <code>module\_invoke\_all('init');</code>), habe aber nur den kernaufruf gefunden). ich weiß nicht, ob dies anders genannt werden kann.</p><p>das ist mein hook\_init ()</p><pre><code>function episkeptis\_achievements\_init(){ dsm('1st execution'); dsm('request\_time: '.format\_date(request\_time, 'custom', 'd/m/y h:i:s').' ('.request\_time.')'); } </code></pre><p>und das ist die ausgabe:</p><pre><code>1st execution request\_time: 09/07/2012 11:20:32 (1341822032) </code></pre><p>dann wurde die nachricht dsm () in <code>dsm('2nd execution');</code> geändert und erneut ausgeführt. dies ist die ausgabe:</p><pre><code>1st execution request\_time: 09/07/2012 11:20:34 (1341822034) 2nd execution request\_time: 09/07/2012 11:22:28 (1341822148) </code></pre><p>sie können sehen, dass der code zweimal ausgeführt wird. beim ersten mal wird jedoch eine alte kopie des codes ausgeführt, beim zweiten mal die aktualisierte kopie. es gibt auch einen zeitunterschied von 2 sekunden.</p><p>dies ist eine d7-version mit php 5.3.10</p>
<p><code>hook\_init()</code> wird von drupal nur einmal für jede angeforderte seite aufgerufen; dies ist der letzte schritt in <a href="http://api.drupal.org/api/drupal/includes!common.inc/function/\_drupal\_bootstrap\_full/7">\_ drupal\_bootstrap\_full ()</a> .</p><pre><code> // drupal 6 // // let all modules take action before menu system handles the request // we do not want this while running update.php. if (!defined('maintenance\_mode') || maintenance\_mode != 'update') { module\_invoke\_all('init'); } </code></pre><pre><code> // drupal 7 // // let all modules take action before the menu system handles the request. // we do not want this while running update.php. if (!defined('maintenance\_mode') || maintenance\_mode != 'update') { // prior to invoking hook\_init(), initialize the theme (potentially a custom // one for this page), so that: // - modules with hook\_init() implementations that call theme() or // theme\_get\_registry() don't initialize the incorrect theme. // - the theme can have hook\_*\_alter() implementations affect page building // (e.g., hook\_form\_alter(), hook\_node\_view\_alter(), hook\_page\_alter()), // ahead of when rendering starts. menu\_set\_custom\_theme(); drupal\_theme\_initialize(); module\_invoke\_all('init'); } </code></pre><p>wenn <code>hook\_init()</code> mehrmals ausgeführt wird, sollten sie herausfinden, warum dies geschieht. soweit ich sehen kann, überprüft keine der implementierungen von <code>hook\_init()</code> in drupal, dass sie zweimal ausgeführt wird (siehe zum beispiel <a href="http://api.drupal.org/api/drupal/modules!system!system.module/function/system\_init/7">system\_init ()</a> oder - <a href="http://api.drupal.org/api/drupal/modules!update!update.module/function/update\_init/7">pdate\_init ()</a> ). wenn dies normalerweise bei drupal der fall ist, prüft <code>update\_init()</code> zunächst, ob es bereits ausgeführt wurde.</p><p>wenn der zähler die anzahl der aufeinanderfolgenden tage ist, an denen sich ein benutzer angemeldet hat, würde ich lieber <code>hook\_init()</code> mit einem code implementieren, der dem folgenden ähnlich ist.</p><pre><code>// drupal 7 function mymodule\_init() { global $user; $result = mymodule\_increase\_counter($user-&gt;uid); if ($result[0]) { // increase the counter; set the other variables. } elseif ($result[1] &gt; 86400) { // the user didn't log in yesterday. } } function mymodule\_date($timestamp) { $date\_time = date\_create('@' . $timestamp); return date\_format($date\_time, 'ymd'); } function mymodule\_increase\_counter($uid) { $last\_timestamp = variable\_get("mymodule\_last\_timestamp\_$uid", 0); if ($last\_timestamp == request\_time) { return array(false, 0); } $result = array( mymodule\_date($last\_timestamp + 86400) == mymodule\_date(request\_time), request\_time - $last\_timestamp, ); variable\_set("mymodule\_last\_timestamp\_$uid", request\_time); return $result; } </code></pre><pre><code>// drupal 6 function mymodule\_init() { global $user; $result = mymodule\_increase\_counter($user-&gt;uid); if ($result[0]) { // increase the counter; set the other variables. } elseif ($result[1] &gt; 86400) { // the user didn't log in yesterday. } } function mymodule\_increase\_counter($uid) { $last\_timestamp = variable\_get("mymodule\_last\_timestamp\_$uid", 0); $result = array(false, time() - $last\_timestamp); if (time() - $last\_timestamp &lt; 20) { return $result; } $result[0] = (mymodule\_date($last\_timestamp + 86400) == mymodule\_date(request\_time)); variable\_set("mymodule\_last\_timestamp\_$uid", time()); return $result; } </code></pre><p>wenn <code>hook\_init()</code> während derselben seitenanforderung zweimal hintereinander aufgerufen wird, enthält <code>request\_time</code> diesen wert und die funktion würde <code>false</code> zurückgeben.</p><p>der code in <code>mymodule\_increase\_counter()</code> ist nicht optimiert; es soll nur ein beispiel zeigen. in einem realen modul würde ich lieber eine datenbanktabelle verwenden, in der der zähler und die anderen variablen gespeichert sind. der grund ist, dass drupal variablen alle in die globale variable <code>$conf</code> geladen werden, wenn drupal bootstraps (siehe <a href="http://api.drupal.org/api/drupal/includes!bootstrap.inc/function/\_drupal\_bootstrap\_variables/7">\_ drupal\_bootstrap\_variables ()</a> und - <a href="http://api.drupal.org/api/drupal/includes!bootstrap.inc/function/variable\_initialize/7">variable\_initialize ()</a> ); wenn sie dafür drupal -variablen verwenden, lädt drupal informationen über alle benutzer, für die sie informationen gespeichert haben, in den speicher, wenn für jede angeforderte seite nur ein benutzerkonto im gespeichert ist globale variable <code>$user</code>.</p><p>wenn sie die anzahl der von den benutzern an aufeinanderfolgenden tagen besuchten seiten zählen, würde ich den folgenden code implementieren.</p><pre><code>// drupal 7 function mymodule\_init() { global $user; $result = mymodule\_increase\_counter($user-&gt;uid); if ($result[0]) { // increase the counter; set the other variables. } elseif ($result[1] &gt; 86400) { // the user didn't log in yesterday. } } function mymodule\_date($timestamp) { $date\_time = date\_create('@' . $timestamp); return date\_format($date\_time, 'ymd'); } function mymodule\_increase\_counter($uid) { $last\_timestamp = variable\_get("mymodule\_last\_timestamp\_$uid", 0); if ($last\_timestamp == request\_time) { return array(false, 0); } $result = array( mymodule\_date($last\_timestamp + 86400) == mymodule\_date(request\_time), request\_time - $last\_timestamp, ); variable\_set("mymodule\_last\_timestamp\_$uid", request\_time); return $result; } </code></pre><pre><code>// drupal 6 function mymodule\_init() { global $user; $result = mymodule\_increase\_counter($user-&gt;uid); if ($result[0]) { // increase the counter; set the other variables. } elseif ($result[1] &gt; 86400) { // the user didn't log in yesterday. } } function mymodule\_increase\_counter($uid) { $last\_timestamp = variable\_get("mymodule\_last\_timestamp\_$uid", 0); $result = array(false, time() - $last\_timestamp); if (time() - $last\_timestamp &lt; 20) { return $result; } $result[0] = (mymodule\_date($last\_timestamp + 86400) == mymodule\_date(request\_time)); variable\_set("mymodule\_last\_timestamp\_$uid", time()); return $result; } </code></pre><p>sie werden feststellen, dass ich in meinem code nicht <code>$user-&gt;access</code> verwende. der grund ist, dass <code>$user-&gt;access</code> während des bootstraps drupal aktualisiert werden kann, bevor <code>hook\_init()</code> aufgerufen wird. der von drupal verwendete sitzungsschreibhandler enthält den folgenden code. (siehe <a href="http://api.drupal.org/api/drupal/includes!session.inc/function/\_drupal\_session\_write/7">\_ drupal\_session\_write ()</a> .)</p><pre><code>// likewise, do not update access time more than once per 180 seconds. if ($user-&gt;uid &amp;&amp; request\_time - $user-&gt;access &gt; variable\_get('session\_write\_interval', 180)) { db\_update('users') -&gt;fields(array( 'access' =&gt; request\_time, )) -&gt;condition('uid', $user-&gt;uid) -&gt;execute(); } </code></pre><p>für einen anderen hook, den sie verwenden können, können sie mit drupal 7 <a href="http://api.drupal.org/api/drupal/modules!system!system.api.php/function/hook\_page\_alter/7">hook\_page\_alter ()</a> verwenden; sie ändern nur nicht den inhalt von <code>$page</code>, sondern erhöhen ihren zähler und ändern ihre variablen.<br> auf drupal 6 können sie <a href="http://api.drupal.org/api/drupal/developer!hooks!core.php/function/hook\_footer/6">hook\_footer ()</a> verwenden, den hook, der von <a href="http://api.drupal.org/api/drupal/includes!theme.inc/function/template\_preprocess\_page/6">template\_preprocess\_page ()</a> aufgerufen wird. sie geben nichts zurück, sondern erhöhen ihren zähler und ändern ihre variablen.</p><p>auf drupal 6 und drupal 7 können sie <a href="http://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook\_exit/7">hook\_exit ()</a> verwenden. beachten sie, dass der hook auch aufgerufen wird, wenn bootstrap nicht vollständig ist. der code konnte keinen zugriff auf funktionen haben, die von modulen oder anderen drupal -funktionen definiert wurden, und sie sollten zuerst überprüfen, ob diese funktionen verfügbar sind. einige funktionen sind immer über <code>hook\_exit()</code> verfügbar, z. b. die in <a href="http://api.drupal.org/api/drupal/includes!bootstrap.inc/7">bootstrap.inc</a> und <a href="http://api.drupal.org/api/drupal/includes!cache.inc/7">cache.inc</a> definierten. der unterschied besteht darin, dass <code>hook\_exit()</code> auch für zwischengespeicherte seiten aufgerufen wird, während <code>hook\_init()</code> für zwischengespeicherte seiten nicht aufgerufen wird.</p><p>als beispiel für code, der von einem drupal -modul verwendet wird, siehe <a href="http://api.drupal.org/api/drupal/modules!statistics!statistics.module/function/statistics\_exit/7">statistics\_exit ()</a> . das statistikmodul protokolliert zugriffsstatistiken für eine site und verwendet, wie sie sehen, <code>hook\_exit()</code> und nicht <code>hook\_init()</code>. um die erforderlichen funktionen aufrufen zu können, wird <a href="http://api.drupal.org/api/drupal/includes!bootstrap.inc/function/drupal\_bootstrap/7">drupal\_bootstrap ()</a> aufgerufen, wobei der richtige parameter übergeben wird, wie im folgenden code.</p><pre><code> // when serving cached pages with the 'page\_cache\_without\_database' // configuration, system variables need to be loaded. this is a major // performance decrease for non-database page caches, but with statistics // module, it is likely to also have 'statistics\_enable\_access\_log' enabled, // in which case we need to bootstrap to the session phase anyway. drupal\_bootstrap(drupal\_bootstrap\_variables); </code></pre><pre><code> if (variable\_get('statistics\_enable\_access\_log', 0)) { drupal\_bootstrap(drupal\_bootstrap\_session); // for anonymous users unicode.inc will not have been loaded. include\_once drupal\_root . '/includes/unicode.inc'; // log this page access. db\_insert('accesslog') -&gt;fields(array( 'title' =&gt; truncate\_utf8(strip\_tags(drupal\_get\_title()), 255), 'path' =&gt; truncate\_utf8($\_get['q'], 255), 'url' =&gt; isset($\_server['http\_referer']) ? $\_server['http\_referer'] : '', 'hostname' =&gt; ip\_address(), 'uid' =&gt; $user-&gt;uid, 'sid' =&gt; session\_id(), 'timer' =&gt; (int) timer\_read('page'), 'timestamp' =&gt; request\_time, )) -&gt;execute(); } </code></pre><h3>aktualisieren</h3><p>möglicherweise gibt es einige verwirrung darüber, wann <code>hook\_init()</code> aufgerufen wird.</p><p><code>hook\_init()</code> wird für jede seitenanforderung aufgerufen, wenn die seite nicht zwischengespeichert ist. es wird nicht einmal für jede seitenanforderung aufgerufen, die vom selben benutzer stammt. wenn sie beispielsweise <a href="http://example.com/admin/appearance/update">http://example.com/admin/appearance/update</a> und dann <a href="http://example.com/admin/reports/status">http://example.com/admin/reports/status</a> besuchen , <code>hook\_init()</code> wird zweimal aufgerufen: eine für jede seite.<br> "der hook wird zweimal aufgerufen" bedeutet, dass es ein modul gibt, das den folgenden code ausführt, sobald drupal seinen bootstrap abgeschlossen hat.</p><pre><code>module\_invoke\_all('init'); </code></pre><p>wenn dies der fall ist, würde die folgende implementierung von <code>hook\_init()</code> zweimal denselben wert anzeigen.</p><pre><code>function mymodule\_init() { watchdog('mymodule', 'request time: !timestamp', array('!timestamp' =&gt; request\_time), watchdog\_debug); } </code></pre><p>wenn ihr code für <code>request\_time</code> zwei werte anzeigt, für die die differenz wie in ihrem fall 2 minuten beträgt, wird der hook nicht zweimal aufgerufen, sondern einmal für jede angeforderte seite, wie es passieren sollte.</p><p><code>request\_time</code> ist in <a href="http://api.drupal.org/api/drupal/includes!bootstrap.inc/7">bootstrap.inc</a> mit der folgenden zeile definiert.</p><pre><code>define('request\_time', (int) $\_server['request\_time']); </code></pre><p>bis die aktuell angeforderte seite nicht an den browser zurückgegeben wird, ändert sich der wert von <code>request\_time</code> nicht. wenn sie einen anderen wert sehen, beobachten sie den auf einer anderen anforderungsseite zugewiesenen wert.</p>
<p>versuche etwas wie</p><pre><code>&lt;ifmodule mod\_expires.c&gt; expiresactive on expiresdefault "access plus 1 seconds" expiresbytype text/html "access plus 1 seconds" expiresbytype image/x-icon "access plus 2592000 seconds" expiresbytype image/gif "access plus 2592000 seconds" expiresbytype image/jpeg "access plus 2592000 seconds" expiresbytype image/png "access plus 2592000 seconds" expiresbytype text/css "access plus 604800 seconds" expiresbytype text/javascript "access plus 86400 seconds" expiresbytype application/x-javascript "access plus 86400 seconds" &lt;/ifmodule&gt; </code></pre><p>oder </p><pre><code>&lt;filesmatch "\.(?i:gif|jpe?g|png|ico|css|js|swf)$"&gt; &lt;ifmodule mod\_headers.c&gt; header set cache-control "max-age=172800, public, must-revalidate" &lt;/ifmodule&gt; &lt;/filesmatch&gt; </code></pre> <p>erwägen sie die verwendung eines <strong> mehrfachauswahl-designs mit token </strong>. die filter-as-you-type-funktion ist nett, aber nicht unbedingt erforderlich. diese funktionieren gut, wenn im allgemeinen anwendungsfall entweder einer oder nur wenige ausgewählt werden. die benutzerfreundlichkeit nimmt jedoch schnell ab, wenn sie viele auswählen müssen, da der benutzer das menü für jedes element erneut aufrufen muss.</p><p><img src="https://i.stack.imgur.com/fth7o.png" alt="multi-select with tokens, via harvesthq.github.com/chosen"></p><ul> <li> <a href="http://harvesthq.github.com/chosen/">http://harvesthq.github.com/chosen/</a> </li> <li> <a href="http://designingwebinterfaces.com/the-multi-select-solution">http://designingwebinterfaces.com/the-multi-select-solution</a> </li> <li> <a href="http://loopj.com/jquery-tokeninput/">http://loopj.com/jquery-tokeninput/</a> </li> </ul><p>sie haben die tokenisierte mehrfacheingabemethode bereits in ihren e-mail-clients gesehen. <img src="https://i.stack.imgur.com/h1aid.png" alt="multi-select-tokens in email"></p><p>wenn häufig mehrere ausgewählt werden, können sie ein kontrollkästchenmenü <strong> </strong> in betracht ziehen. der unterschied besteht darin, dass das dropdown-menü über alle klicks hinweg dauerhaft bleibt (und die mehrfachauswahl visuell kommuniziert). daher kann der benutzer mit klick-klick-klick schnell mehrere elemente auswählen. für unsere web-app möchten wir dieses design durch hinzufügen der token-funktionalität verbessern.</p><p><img src="https://i.stack.imgur.com/zqizh.png" alt="checkbox menu, via realestate.com.au"></p><ul> <li> <a href="http://www.realestate.com.au/">http://www.realestate.com.au/</a> </li> <li> <a href="http://blogfreakz.com/jquery/jquery-dropdown-check-list/">http://blogfreakz.com/jquery/jquery-dropdown-check-list/</a> </li> </ul> Eine geöffnete Datei wird durch einen sogenannten *file descriptor* repräsentiert.  


Mit 


```
[anweisung] n> [datei]
```
 wird [anweisung] ausgeführt und das, was der dadurch erzeugte Prozess in die Datei mit file descriptor n schreibt, wird stattdessen in die Datei [datei] gerschrieben.   
Beim Programmstart werden üblicherweise automatisch drei Dateien geöffnet:

    0: stdin Die Standardeingabe  


    1: stdout Die Standardausgabe

    2: stderr Die Fehlerausgabe

**Beispiele.**


```
ls 1> files.txt  

```
schreibt den Inhalt des aktuellen Ordners in die Datei files.txt und zeigt Fehlermeldungen am Bildschirm an. Die 1 hätte hier weggelassen werden können.  

```
ls 2> ls.err  

```
Zeigt den Inhalt des aktuellen Ordners am Bildschirm an und schreibt Fehlermeldungen in die Datei ls.err.
```
ls 2>ls.err 1> files.txt  

```
Schreibt Inhalt des aktuellen Ordners in die Datei files.txt und Fehlermeldungen in die Datei ls.err.
```
ls 2>&1 | cat > output  

```
Schreibt Inhalt des aktuellen Ordners und Fehlermeldungen in die Datei output. Es lohnt sich, einen Blick auf diesen [`Blog Post`](http://lostechies.com/jimmybogard/2012/07/20/choosing-an-orm-strategy/) werfen, aber letztendlich werden die Kriterien von Ihnen festgelegt. Sie müssen entscheiden, ob 

* schnelle Entwicklung
* Performance
* Code-zuerst
* DB zuerst

 oder was auch immer Sie suchen und priorisieren Sie die Liste basierend auf, was noch wichtiger ist. Dann verwenden Sie diese Liste, um Ihre Forschung zusammenzustellen. Hallo Luca
* Falls du Entfernungsanträge gestellt hast, nimm diese zurück.
* Und schau beim URL Test in der SC genau ob G. eventuell ein Duplikat kennt.


 
Ansonsten kannst du leider gar nichts tun, außer warten bis sich G. bequemt nochmals vorbeizukommen. Das ist leider immer wieder bei WP CMS der Fall durch dieses unsinnige auf "Noindex" stellen, das Google danach für lange Zeit immer von einem Noindex ausgeht, da hilft auch ein Antrag auf Neuindexierung wenig.
 
lg
PeVy dazu gibt es zwischenzeitlich eine stellungnahme :
https://discussions.tomtom.com/de/discussion/comment/1651174/#comment\_1651174 evtl. suchst du sowas:
https://stackoverflow.com/questions/15563921/how-to-detect-incoming-calls-in-an-android-device

da sind zwei möglichkeiten aufgezeigt... Hey [@Olaf3](/c/user/viewprofilepage/user-id/696053) 


Da Shopify [Canonical URLs und Tags](https://help.shopify.com/de/manual/promoting-marketing/seo/seo-overview#seo-verbessern) verwendet werden beide URLs für SEO-Zwecke als identisch und nicht als doppelte Seiten behandelt. 


Wir haben hier einen vollständigen Leitfaden für die Einrichtung kanonischer Tags innerhalb [deines Theme Codes hier](https://help.shopify.com/themes/development/getting-started/search-engine-optimization#duplicate-content-and-canonical-urls) falls das hilfreich ist. Vielleicht sind auch Punkte 5, 6 und 8 in [diesem Blog Artikel](https://www.searchenginejournal.com/technical-seo/url-structure/#close) hilfreich. Es wird empfohlen, notfalls eine 301-Umleitung einzurichten und eine XML-Sitemap zu erstellen.


VG,


 



 **Gabe | Social Care @ Shopify**  
   
  - War meine Antwort hilfreich? Klicke **Like** um es mich wissen zu lassen!   
  - Wurde deine Frage beantwortet? Markiere es als **Als Lösung anerkennen**   
 

 Um mehr zu erfahren, besuche unseren [Shopify Help Center](https://help.shopify.com/de/?&utm_source=community&utm_medium=web&utm_campaign=signature&utm_content=de<br>) oder unseren [Shopify Blog](https://www.shopify.de/blog?&utm_source=community&utm_medium=web&utm_campaign=signature&utm_content=de) > 
> Quote: Liegt es daran, dass es zweimal dieselbe E-mailadresse ist? 
> 
> 
> 


Soweit ich weiß benötigt jedes Konto eine **eineindeutige** E-Mail Adresse.


Doppeltanmeldungen sollte es eigentlich nicht geben dürfen.


Wurde evtl. Facebook, GooglePlus & Co. (statt einer E-Mail) für den Login in das aktuellere Konto verwendet?   

Laut anderen Nutzern wird dann teils das alte Profil überschrieben bzw. umbenannt.


Besitzt überhaupt das neuere Konto eine zugeordnete E-Mail Adresse?


Wenn es in der App mit dem Anmelden nicht klappt:   

Schon mal im Web [www.duolingo.com](http://www.duolingo.com) versucht?


Entweder man gibt seinen Benutzernamen ein ODER man verwendet eine *eineindeutige* E-Mail Adresse + Passwort.


Wie lautet denn das zweite Konto?   

Ist von Duolingo auf irgendwelche kryptischen Buchstaben und Nummern/Zeichen zurückgesetzt worden?


Wenn die Passwörter gleich sind, müßtest zumindest über den Login **per Username** in das andere Konto kommen können.


Habe ich es richtig verstanden dass in der Inbox E-mails vom Absender [duolingo.com](http://duolingo.com) zum neueren Konto wegen Streakverlust & Co. eintreffen und man somit sieht, dass auch das zweite Konto die gleiche E-Mail Adresse verwendet?


Ja wie denn das?


Vielleicht irgendeine Alias / Sub E-Mail Adresse verwendet die jetzt im gleichen Posteingang herauskommt?


Wurde die option "I cannot access my account" beim Ticket verwendet: <https://support.duolingo.com/hc/en-us/requests/new>


Oder versehentlich "nur" einen Bug Report submittet?   

Zur letztere "normale" Option enthält man - außer der Auto-Reply zum Eingang des Tickets - keinerlei Rückmeldungen vom Support/Entwicklern!!! Hallo, 
  

  
schauen Sie unter "Dienste" nach, ob "Druckwarteschlange" ausgeführt wird und schauen Sie mal in [diesen CCM-Artikel](/faq/827-druckspoolerdienst-aktivieren-deaktivieren), wie sie ihn ggf. aktivieren. 
  

  
Gruß vom CCM-Team